refactor!: use :global() for custom styles (#1940)

* Prefix custom class selectors with `bx--` (primarily used in custom UI Shell components)
* Use `:global` scope so that selector names are not hashed
This commit is contained in:
metonym 2024-03-23 13:11:44 -07:00 committed by GitHub
commit d5a11489f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 70 additions and 49 deletions

View file

@ -1624,12 +1624,12 @@ None.
### Slots ### Slots
| Slot name | Default | Props | Fallback | | Slot name | Default | Props | Fallback |
| :-------- | :------ | :---- | :--------------------------------------------------------------------- | | :-------- | :------ | :---- | :--------------------------------------------------------------------------------------------------- |
| -- | Yes | -- | -- | | -- | Yes | -- | -- |
| closeIcon | No | -- | <code>&lt;svelte:component this="{closeIcon}" size="{20}" /&gt;</code> | | closeIcon | No | -- | <code>&lt;svelte:component this="{closeIcon}" size="{20}" /&gt;</code> |
| icon | No | -- | <code>&lt;svelte:component this="{icon}" size="{20}" /&gt;</code> | | icon | No | -- | <code>&lt;svelte:component this="{icon}" size="{20}" /&gt;</code> |
| text | No | -- | <code>{#if text}&lt;span&gt;{text}&lt;/span&gt;{/if}</code> | | text | No | -- | <code>{#if text}&lt;span class:bx--header\_\_action-text="{true}"&gt;{text}&lt;/span&gt;{/if}</code> |
### Events ### Events
@ -1835,9 +1835,9 @@ export interface HeaderSearchResult {
### Slots ### Slots
| Slot name | Default | Props | Fallback | | Slot name | Default | Props | Fallback |
| :-------- | :------ | :---------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------ | | :-------- | :------ | :---------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| -- | Yes | <code>{ result: HeaderSearchResult; index: number } </code> | <code>{result.text}<br /> {#if result.description}&lt;span&gt; {result.description}&lt;/span&gt;{/if}</code> | | -- | Yes | <code>{ result: HeaderSearchResult; index: number } </code> | <code>{result.text}<br /> {#if result.description}&lt;span<br /> class:bx--header-search-menu-description="{true}"<br /> &gt; {result.description}&lt;/span<br /> &gt;{/if}</code> |
### Events ### Events

View file

@ -4998,7 +4998,7 @@
{ {
"name": "text", "name": "text",
"default": false, "default": false,
"fallback": "{#if text}<span>{text}</span>{/if}", "fallback": "{#if text}<span class:bx--header__action-text=\"{true}\">{text}</span>{/if}",
"slot_props": "{}" "slot_props": "{}"
} }
], ],
@ -5396,7 +5396,7 @@
{ {
"name": "__default__", "name": "__default__",
"default": true, "default": true,
"fallback": "{result.text}\n {#if result.description}<span> {result.description}</span>{/if}", "fallback": "{result.text}\n {#if result.description}<span\n class:bx--header-search-menu-description=\"{true}\"\n > {result.description}</span\n >{/if}",
"slot_props": "{ result: HeaderSearchResult; index: number }" "slot_props": "{ result: HeaderSearchResult; index: number }"
} }
], ],

View file

@ -70,7 +70,7 @@
type="button" type="button"
class:bx--header__action="{true}" class:bx--header__action="{true}"
class:bx--header__action--active="{isOpen}" class:bx--header__action--active="{isOpen}"
class:action-text="{text}" class:bx--header__action--text="{text}"
{...$$restProps} {...$$restProps}
on:click on:click
on:click|stopPropagation="{() => { on:click|stopPropagation="{() => {
@ -88,7 +88,7 @@
</slot> </slot>
{/if} {/if}
<slot name="text"> <slot name="text">
{#if text}<span>{text}</span>{/if} {#if text}<span class:bx--header__action-text="{true}">{text}</span>{/if}
</slot> </slot>
</button> </button>
{#if isOpen} {#if isOpen}
@ -106,7 +106,7 @@
{/if} {/if}
<style> <style>
.action-text { :global(.bx--header__action--text) {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
width: auto; width: auto;
@ -123,7 +123,7 @@
color: #f4f4f4; color: #f4f4f4;
} }
.action-text > span { :global(.bx--header__action-text) {
margin-left: 0.75rem; margin-left: 0.75rem;
} }
</style> </style>

View file

@ -33,7 +33,7 @@
</a> </a>
<style> <style>
.bx--header__action { :global(.bx--header__action) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View file

@ -1,8 +1,6 @@
{#if $$slots.default} {#if $$slots.default}
<li> <li class:bx--header-panel-divider={true}>
<span> <slot />
<slot />
</span>
</li> </li>
{/if} {/if}
<hr class:bx--switcher__item--divider="{true}" /> <hr class:bx--switcher__item--divider="{true}" />
@ -14,11 +12,8 @@
* from https://carbondesignsystem.com/ as a reference. * from https://carbondesignsystem.com/ as a reference.
*/ */
li { :global(.bx--header-panel-divider) {
margin: 2rem 1rem 0; margin: 2rem 1rem 0;
color: #525252;
}
span {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1.3; line-height: 1.3;
letter-spacing: 0.02rem; letter-spacing: 0.02rem;

View file

@ -60,16 +60,30 @@
}}" }}"
/> />
<div bind:this="{refSearch}" role="search" class:active> <div
<label for="search-input" id="search-label">Search</label> bind:this="{refSearch}"
<div aria-owns="search-menu" aria-haspopup="menu"> class:bx--header__search="{true}"
role="search"
class:bx--header__search--active="{active}"
>
<label
class:bx--header__search-label="{true}"
for="search-input"
id="search-label">Search</label
>
<div
class:bx--header__search-menu="{true}"
aria-owns="search-menu"
aria-haspopup="menu"
>
<button <button
type="button" type="button"
aria-label="Search" aria-label="Search"
aria-expanded="{active}" aria-expanded="{active}"
tabindex="{active ? '-1' : '0'}" tabindex="{active ? '-1' : '0'}"
class:bx--header-search-button="{true}"
class:bx--header__action="{true}" class:bx--header__action="{true}"
class:disabled="{active}" class:bx--header-search-button--disabled="{active}"
on:click="{() => { on:click="{() => {
active = true; active = true;
}}" }}"
@ -82,7 +96,8 @@
autocomplete="off" autocomplete="off"
placeholder="Search..." placeholder="Search..."
tabindex="{active ? '0' : '-1'}" tabindex="{active ? '0' : '-1'}"
class:active class:bx--header__search-input="{true}"
class:bx--header__search--active="{active}"
{...$$restProps} {...$$restProps}
id="search-input" id="search-input"
aria-autocomplete="list" aria-autocomplete="list"
@ -135,7 +150,8 @@
aria-label="Clear search" aria-label="Clear search"
tabindex="{active ? '0' : '-1'}" tabindex="{active ? '0' : '-1'}"
class:bx--header__action="{true}" class:bx--header__action="{true}"
class:hidden="{!active}" class:bx--header-search-button="{true}"
class:bx--header-search-button--hidden="{!active}"
on:click="{() => { on:click="{() => {
reset(); reset();
dispatch('clear'); dispatch('clear');
@ -147,7 +163,12 @@
{#if active && results.length > 0} {#if active && results.length > 0}
<!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role --> <!-- svelte-ignore a11y-no-noninteractive-element-to-interactive-role -->
<ul aria-labelledby="search-label" role="menu" id="search-menu"> <ul
aria-labelledby="search-label"
role="menu"
id="search-menu"
class:bx--header-search-menu="{true}"
>
{#each results as result, i} {#each results as result, i}
<li role="none"> <li role="none">
<a <a
@ -155,7 +176,9 @@
id="search-menuitem-{i}" id="search-menuitem-{i}"
role="menuitem" role="menuitem"
href="{result.href}" href="{result.href}"
class:selected="{selectedId === `search-menuitem-${i}`}" class:bx--header-search-menu-item="{true}"
class:bx--header-search-menu-item--selected="{selectedId ===
`search-menuitem-${i}`}"
on:click|preventDefault="{async () => { on:click|preventDefault="{async () => {
selectedResultIndex = i; selectedResultIndex = i;
await tick(); await tick();
@ -164,7 +187,10 @@
> >
<slot result="{result}" index="{i}"> <slot result="{result}" index="{i}">
{result.text} {result.text}
{#if result.description}<span> {result.description}</span>{/if} {#if result.description}<span
class:bx--header-search-menu-description="{true}"
> {result.description}</span
>{/if}
</slot> </slot>
</a> </a>
</li> </li>
@ -174,7 +200,7 @@
</div> </div>
<style> <style>
label { :global(.bx--header__search-label) {
position: absolute; position: absolute;
width: 1px; width: 1px;
height: 1px; height: 1px;
@ -187,7 +213,7 @@
clip: rect(0, 0, 0, 0); clip: rect(0, 0, 0, 0);
} }
[role="search"] { :global(.bx--header__search) {
position: relative; position: relative;
display: flex; display: flex;
max-width: 28rem; max-width: 28rem;
@ -200,23 +226,23 @@
background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9); background 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
} }
[role="search"]:not(.active) { :global(.bx--header__search:not(.bx--header__search--active)) {
max-width: 3rem; max-width: 3rem;
background-color: #161616; background-color: #161616;
} }
[role="search"].active { :global(.bx--header__search.bx--header__search--active) {
outline: 2px solid #fff; outline: 2px solid #fff;
outline-offset: -2px; outline-offset: -2px;
} }
[aria-haspopup="menu"] { :global(.bx--header__search-menu) {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
border-bottom: 1px solid #393939; border-bottom: 1px solid #393939;
} }
input { :global(.bx--header__search-input) {
width: 100%; width: 100%;
height: 3rem; height: 3rem;
padding: 0; padding: 0;
@ -232,12 +258,12 @@
transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9); transition: opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
} }
input:not(.active) { :global(.bx--header__search-input:not(.bx--header__search--active)) {
opacity: 0; opacity: 0;
pointer-events: none; pointer-events: none;
} }
button { :global(.bx--header-search-button) {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -250,21 +276,21 @@
opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9); opacity 0.11s cubic-bezier(0.2, 0, 0.38, 0.9);
} }
.disabled { :global(.bx--header-search-button--disabled) {
border: none; border: none;
pointer-events: none; pointer-events: none;
} }
[aria-label="Clear search"]:hover { :global(.bx--header-search-button:hover) {
background-color: #4c4c4c; background-color: #4c4c4c;
} }
.hidden { :global(.bx--header-search-button--hidden) {
opacity: 0; opacity: 0;
display: none; display: none;
} }
ul { :global(.bx--header-search-menu) {
position: absolute; position: absolute;
z-index: 10000; z-index: 10000;
padding: 1rem 0; padding: 1rem 0;
@ -277,7 +303,7 @@
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.5); box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.5);
} }
[role="menuitem"] { :global(.bx--header-search-menu-item) {
padding: 6px 1rem; padding: 6px 1rem;
cursor: pointer; cursor: pointer;
font-size: 0.875rem; font-size: 0.875rem;
@ -293,13 +319,13 @@
color: #c6c6c6; color: #c6c6c6;
} }
.selected, :global(.bx--header-search-menu-item--selected),
[role="menuitem"]:hover { :global(.bx--header-search-menu-item:hover) {
background-color: #353535; background-color: #353535;
color: #f4f4f4; color: #f4f4f4;
} }
[role="menuitem"] span { :global(.bx--header-search-menu-description) {
font-size: 0.75rem; font-size: 0.75rem;
font-weight: 400; font-weight: 400;
line-height: 1.34; line-height: 1.34;