@ds-mo/ui 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -3
- package/dist/components/ds-badge.js +1 -1
- package/dist/components/ds-badge.js.map +1 -1
- package/dist/components/ds-banner.js +1 -1
- package/dist/components/ds-banner.js.map +1 -1
- package/dist/components/ds-bar-nav-action.js +1 -1
- package/dist/components/ds-bar-nav.js +1 -1
- package/dist/components/ds-bar-nav.js.map +1 -1
- package/dist/components/ds-button-group.js +1 -1
- package/dist/components/ds-checkbox.js +1 -1
- package/dist/components/{ds-label-wrap.d.ts → ds-chip.d.ts} +4 -4
- package/dist/components/ds-chip.js +2 -0
- package/dist/components/ds-chip.js.map +1 -0
- package/dist/components/ds-divider.js +1 -1
- package/dist/components/ds-divider.js.map +1 -1
- package/dist/components/ds-empty-state.js +1 -1
- package/dist/components/ds-fade.js +1 -1
- package/dist/components/ds-fade.js.map +1 -1
- package/dist/components/ds-field.js +1 -1
- package/dist/components/ds-header.js +1 -1
- package/dist/components/ds-icon.js +1 -1
- package/dist/components/ds-input.js +1 -1
- package/dist/components/ds-modal.js +1 -1
- package/dist/components/ds-modal.js.map +1 -1
- package/dist/components/ds-panel-nav.js +1 -1
- package/dist/components/ds-panel-nav.js.map +1 -1
- package/dist/components/ds-radio-group.js +1 -1
- package/dist/components/ds-radio-group.js.map +1 -1
- package/dist/components/ds-scrollbar.js +1 -1
- package/dist/components/ds-select.js +1 -1
- package/dist/components/ds-sidebar.js +1 -1
- package/dist/components/ds-sidebar.js.map +1 -1
- package/dist/components/ds-slider.js +1 -1
- package/dist/components/ds-slider.js.map +1 -1
- package/dist/components/ds-surface.js +1 -1
- package/dist/components/ds-tab-group-nav.js +1 -1
- package/dist/components/ds-tab-group.js +1 -1
- package/dist/components/ds-tab-group.js.map +1 -1
- package/dist/components/ds-table.js +1 -1
- package/dist/components/ds-table.js.map +1 -1
- package/dist/components/ds-tag.js +1 -1
- package/dist/components/ds-tag.js.map +1 -1
- package/dist/components/ds-text.js +1 -1
- package/dist/components/ds-toast-provider.js +1 -1
- package/dist/components/ds-toggle-button-group.js +1 -1
- package/dist/components/ds-toggle-button.js +1 -1
- package/dist/components/ds-toggle.js +1 -1
- package/dist/components/ds-tooltip.js +1 -1
- package/dist/components/p-B_enucPQ.js +2 -0
- package/dist/components/p-B_enucPQ.js.map +1 -0
- package/dist/components/p-DOtcc9UU.js +2 -0
- package/dist/components/p-DOtcc9UU.js.map +1 -0
- package/dist/components/{p-H89PzqGU.js → p-DrDrPeVV.js} +2 -2
- package/dist/components/p-OT-Q-NxH.js +2 -0
- package/dist/components/p-OT-Q-NxH.js.map +1 -0
- package/dist/components/{p-Dd0GrKaF.js → p-U1A-rprN.js} +2 -2
- package/dist/components/p-X1N_ggsY.js +2 -0
- package/dist/components/p-X1N_ggsY.js.map +1 -0
- package/dist/components/p-qfvbc9w-.js +2 -0
- package/dist/components/p-qfvbc9w-.js.map +1 -0
- package/dist/types/.stencil/Badge/Badge.d.ts +12 -0
- package/dist/types/.stencil/Badge/index.d.ts +1 -1
- package/dist/types/.stencil/Chip/Chip.d.ts +30 -0
- package/dist/types/.stencil/Chip/index.d.ts +2 -0
- package/dist/types/.stencil/Divider/Divider.d.ts +14 -0
- package/dist/types/.stencil/Fade/Fade.d.ts +17 -2
- package/dist/types/.stencil/Fade/index.d.ts +1 -1
- package/dist/types/.stencil/Tag/Tag.d.ts +0 -17
- package/dist/types/.stencil/Tag/index.d.ts +1 -1
- package/dist/types/.stencil/Text/Text.d.ts +2 -0
- package/dist/types/components.d.ts +283 -143
- package/package.json +12 -5
- package/src/angular/index.ts +1 -1
- package/src/angular/proxies.ts +51 -51
- package/src/react/components.ts +1 -1
- package/src/react/ds-chip.ts +35 -0
- package/src/react/ds-tag.ts +3 -12
- package/src/wc/components/Badge/Badge.tsx +58 -8
- package/src/wc/components/Badge/index.ts +1 -1
- package/src/wc/components/Banner/Banner.tsx +2 -2
- package/src/wc/components/BarNav/BarNav.tsx +7 -1
- package/src/wc/components/BarNavAction/BarNavAction.tsx +9 -1
- package/src/wc/components/Chip/Chip.tsx +127 -0
- package/src/wc/components/Chip/index.ts +1 -0
- package/src/wc/components/Divider/Divider.tsx +88 -4
- package/src/wc/components/Fade/Fade.tsx +86 -6
- package/src/wc/components/Fade/index.ts +1 -1
- package/src/wc/components/PanelNav/PanelNav.tsx +17 -1
- package/src/wc/components/TabGroup/TabGroup.tsx +9 -1
- package/src/wc/components/TabGroupNav/TabGroupNav.tsx +9 -1
- package/src/wc/components/Tag/Tag.tsx +3 -70
- package/src/wc/components/Tag/index.ts +1 -1
- package/src/wc/components/Text/Text.tsx +3 -0
- package/src/wc/components.d.ts +283 -143
- package/dist/components/ds-label-wrap.js +0 -2
- package/dist/components/ds-label-wrap.js.map +0 -1
- package/dist/components/p-CMyQsk0K.js +0 -2
- package/dist/components/p-CMyQsk0K.js.map +0 -1
- package/dist/components/p-Vwlmhl4E.js +0 -2
- package/dist/components/p-Vwlmhl4E.js.map +0 -1
- package/dist/components/p-woooYulR.js +0 -2
- package/dist/components/p-woooYulR.js.map +0 -1
- package/dist/types/.stencil/LabelWrap/LabelWrap.d.ts +0 -15
- package/src/react/ds-label-wrap.ts +0 -26
- package/src/wc/components/LabelWrap/LabelWrap.tsx +0 -38
- /package/dist/components/{p-H89PzqGU.js.map → p-DrDrPeVV.js.map} +0 -0
- /package/dist/components/{p-Dd0GrKaF.js.map → p-U1A-rprN.js.map} +0 -0
package/README.md
CHANGED
|
@@ -50,7 +50,6 @@ Then use `<ds-*>` tags in templates. **Angular** can import Stencil-generated pr
|
|
|
50
50
|
- **Input** — text input field
|
|
51
51
|
- **Slider** — range slider
|
|
52
52
|
- **Field** — label + input wrapper
|
|
53
|
-
- **LabelWrap** — label + content wrapper with layout variants
|
|
54
53
|
- **Divider** — horizontal or vertical rule
|
|
55
54
|
|
|
56
55
|
### Actions
|
|
@@ -65,8 +64,9 @@ Then use `<ds-*>` tags in templates. **Angular** can import Stencil-generated pr
|
|
|
65
64
|
- **Radio** — single-select radio input
|
|
66
65
|
|
|
67
66
|
### Data display
|
|
68
|
-
- **Tag** —
|
|
69
|
-
- **
|
|
67
|
+
- **Tag** — static metadata label with intent coloring
|
|
68
|
+
- **Chip** — interactive or removable metadata chip
|
|
69
|
+
- **Badge** — compact counter or notification dot
|
|
70
70
|
- **Table** — sortable, paginated data table
|
|
71
71
|
- **Accordion** — collapsible content sections
|
|
72
72
|
- **Pagination** — page navigation control
|
|
@@ -114,3 +114,82 @@ Components that accept icons use named slots:
|
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
Pass any element into `slot="icon"`. Works with `@ds-mo/icons` or any custom SVG element.
|
|
117
|
+
|
|
118
|
+
## Figma Code Connect
|
|
119
|
+
|
|
120
|
+
This repo includes [Figma Code Connect](https://developers.figma.com/docs/code-connect/) templates under `code-connect/` so Dev Mode can show curated snippets (e.g. React wrappers from `@ds-mo/ui/react`).
|
|
121
|
+
|
|
122
|
+
**Prerequisites**
|
|
123
|
+
|
|
124
|
+
- Node 18+ (same as the rest of the project).
|
|
125
|
+
- A Figma **personal access token** with **Code Connect (Write)** and **File content (Read)**. Set it locally only — never commit it:
|
|
126
|
+
- `export FIGMA_ACCESS_TOKEN='…'`, or
|
|
127
|
+
- pass `--token` / `-t` when publishing.
|
|
128
|
+
|
|
129
|
+
**CLI**
|
|
130
|
+
|
|
131
|
+
The [`@figma/code-connect`](https://www.npmjs.com/package/@figma/code-connect) package is a devDependency. Use `npx` from the repo root (or install `@figma/code-connect` globally and run `figma connect …`):
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npx figma connect --help
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
You should see subcommands including `publish`, `unpublish`, `create`, and `preview`.
|
|
138
|
+
|
|
139
|
+
**Config**
|
|
140
|
+
|
|
141
|
+
- `figma.config.json` — include glob `code-connect/published/**/*.figma.ts`, snippet label `React`, language `jsx`.
|
|
142
|
+
- `tsconfig.figma.json` — optional; point your editor at it for `figma` template typings (`types: ["@figma/code-connect/figma-types"]`).
|
|
143
|
+
|
|
144
|
+
**Scripts**
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run figma:connect:publish:dry-run # hits Figma API; needs FIGMA_ACCESS_TOKEN or --token
|
|
148
|
+
npm run figma:connect:publish # publish mappings (same token requirement)
|
|
149
|
+
npm run figma:connect:preview # local preview of snippets from templates
|
|
150
|
+
npm run typecheck:figma # typecheck template files only
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**First publish**
|
|
154
|
+
|
|
155
|
+
1. Copy `code-connect/examples/ds-icon.figma.ts` to `code-connect/published/DsIcon.figma.ts`, then set the `// url=…` line from Figma → **Copy link to selection** (see `code-connect/README.md`).
|
|
156
|
+
2. Ensure Figma’s GitHub / Code Connect integration points at **this** `compomo` repo and branch.
|
|
157
|
+
3. Run `npm run figma:connect:publish:dry-run`, then `npm run figma:connect:publish`.
|
|
158
|
+
|
|
159
|
+
Each contributor can use their own `FIGMA_ACCESS_TOKEN` in a local shell or `.env.local` (gitignored); do not commit tokens.
|
|
160
|
+
|
|
161
|
+
### Dev Mode vs “the template” (why mapping exists)
|
|
162
|
+
|
|
163
|
+
- **The canvas** is whatever designers built (variant names like `Type = Main`, nested structure, etc.). Code Connect does **not** rewrite your Figma file.
|
|
164
|
+
- **Dev Mode** can show a **link to your repo file** (e.g. `Icon.tsx`) when you connect the repo — that answers “where is this implemented?”
|
|
165
|
+
- The **Code Connect snippet** is the **copy-paste example** Figma shows in Inspect. That text comes from **your published templates** (or from other Figma features like MCP context), not from magically knowing your Stencil prop names.
|
|
166
|
+
|
|
167
|
+
So: if Figma props already match your API (`intent`, `appearance`), your template can be a thin wrapper and life is easy. If they **do not** match (legacy `Type` vs real `intent`), the template is where you **translate** so the snippet still shows **canonical** usage. You are not making Dev Mode “look like Figma internals” — you are choosing what **engineers should copy** when names diverge.
|
|
168
|
+
|
|
169
|
+
### GitHub Actions — auto-publish on `main` (optional)
|
|
170
|
+
|
|
171
|
+
This repo includes [`.github/workflows/figma-code-connect.yml`](.github/workflows/figma-code-connect.yml). It runs `npm run figma:connect:publish` when **`main`** changes under `code-connect/`, `figma.config.json`, or `tsconfig.figma.json`, and on **manual** “Run workflow”.
|
|
172
|
+
|
|
173
|
+
**1. Create a Figma personal access token**
|
|
174
|
+
|
|
175
|
+
1. Figma → **Settings** (avatar) → **Security** (or **Personal access tokens** depending on UI).
|
|
176
|
+
2. **Generate new token** with at least **File content (Read)** and **Code Connect (Write)** (same scopes as local publish).
|
|
177
|
+
3. Copy the token once; you will not see it again.
|
|
178
|
+
|
|
179
|
+
**2. Add it as a GitHub Actions secret**
|
|
180
|
+
|
|
181
|
+
1. Open the repo on GitHub: `https://github.com/zainadeel/compomo` (or your fork’s **Settings** if you only care about that fork).
|
|
182
|
+
2. **Settings** → **Secrets and variables** → **Actions**.
|
|
183
|
+
3. **New repository secret**
|
|
184
|
+
- **Name:** `FIGMA_ACCESS_TOKEN` (must match the workflow exactly).
|
|
185
|
+
- **Secret:** paste the token → **Add secret**.
|
|
186
|
+
|
|
187
|
+
**3. Confirm the workflow**
|
|
188
|
+
|
|
189
|
+
- **Actions** tab → **Figma Code Connect** → run **workflow_dispatch** once to verify green, then merge a small change under `code-connect/` to test the `push` path.
|
|
190
|
+
|
|
191
|
+
If the secret is missing, the publish step fails with Figma’s “no access token” style error until you add it.
|
|
192
|
+
|
|
193
|
+
### Icon batch files — CompoMo vs IcoMo
|
|
194
|
+
|
|
195
|
+
**Publish from CompoMo.** The batch JSON and `.figma.batch.ts` live in **this** repo (next to `figma.config.json`), and `figma connect publish` runs here. The **snippet** should show how apps use **`@ds-mo/ui`** (e.g. `<ds-icon name="Bell" />` or `<DsIcon name="Bell" />`). **`name`** values must match **IcoMo** export keys, but the **mapping files and CI job** belong to **CompoMo** because that is the package that owns `<ds-icon>` and the Dev Mode story for product engineers.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{B as o,d as s}from"./p-B_enucPQ.js";const t=o;const c=s;export{t as DsBadge,c as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-badge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[
|
|
1
|
+
{"version":3,"names":[],"sources":[],"mappings":"","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as s,c as n,h as t,a as i,t as a}from"./index.js";const r=()=>`.banner-surface.sc-ds-banner{position:relative;display:flex;flex-direction:column;overflow:hidden;border-radius:var(--dimension-radius-075)}.banner-header-surface.sc-ds-banner{width:100%;height:var(--dimension-space-100);flex-shrink:0;overflow:hidden;border-bottom:var(--dimension-stroke-width-015) solid var(--color-border-primary)}.banner-header.sc-ds-banner{width:100%;height:100%;background:repeating-linear-gradient( -45deg, var(--banner-content), var(--banner-content) var(--dimension-size-100), transparent var(--dimension-size-100), transparent var(--dimension-size-200) )}.banner-body.sc-ds-banner{padding:var(--dimension-space-075);min-height:var(--dimension-size-400);display:flex;align-items:flex-start;gap:var(--dimension-space-075)}.banner-message.sc-ds-banner{color:var(--banner-content);line-height:var(--typography-lineheight-md);display:block;flex:1;min-width:0}.banner-dismiss.sc-ds-banner{background:none;border:none;margin:0;padding:var(--dimension-space-025);color:var(--banner-content);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:var(--dimension-radius-050);position:relative;font-size:18px;line-height:1}.banner-dismiss.sc-ds-banner::before{content:'';position:absolute;inset:0;border-radius:inherit;background-color:transparent;transition:var(--effect-transition-interaction-background-short-2, background-color var(--effect-motion-short-2));pointer-events:none}.banner-dismiss.sc-ds-banner:hover::before{background-color:var(--color-interaction-hover)}.banner-dismiss.sc-ds-banner:active::before{background-color:var(--color-interaction-pressed)}.banner-dismiss.sc-ds-banner:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-stroke-width-015)}.floating-position.sc-ds-banner{position:fixed;top:var(--dimension-space-200);left:50%;transform:translateX(-50%);pointer-events:none}.floating-toast.sc-ds-banner{pointer-events:auto;animation:bannerFadeIn var(--effect-motion-short-2, 150ms) forwards}.floating-toast--closing.sc-ds-banner{animation:bannerFadeOut var(--effect-motion-short-3, 200ms) forwards}@keyframes bannerFadeIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes bannerFadeOut{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-4px)}}`;const o=200;const d=4e3;const l=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsDismiss=n(this,"dsDismiss");this.intent="neutral";this.contrast="medium";this.message="";this.header=false;this.floating=false;this.showDismiss=false;this.dismissLabel="Dismiss";this.closing=false;this.dismissTimer=null;this.closeTimer=null}componentDidLoad(){if(this.floating&&this.message)this.scheduleDismiss()}onMessageChange(e){if(this.floating&&e){this.closing=false;this.scheduleDismiss()}}disconnectedCallback(){this.clearTimers()}clearTimers(){if(this.dismissTimer){clearTimeout(this.dismissTimer);this.dismissTimer=null}if(this.closeTimer){clearTimeout(this.closeTimer);this.closeTimer=null}}scheduleDismiss(){this.clearTimers();this.dismissTimer=setTimeout((()=>{this.dismissTimer=null;this.beginClose()}),d)}beginClose(){this.clearTimers();if(this.floating){this.closing=true;this.closeTimer=setTimeout((()=>{this.closing=false;this.closeTimer=null;this.dsDismiss.emit()}),o)}else{this.dsDismiss.emit()}}getContentColor(){if(this.contrast==="bold")return"var(--color-foreground-on-bold-background-primary)";const e=this.contrast==="faint"?"bold":this.contrast==="medium"?"strong":"medium";return`var(--color-foreground-${e}-${this.intent})`}getBg(){return`var(--color-background-${this.contrast}-${this.intent})`}getElevation(){return this.floating?"var(--effect-elevation-elevated-floating
|
|
1
|
+
import{p as e,H as s,c as n,h as t,a as i,t as a}from"./index.js";const r=()=>`.banner-surface.sc-ds-banner{position:relative;display:flex;flex-direction:column;overflow:hidden;border-radius:var(--dimension-radius-075)}.banner-header-surface.sc-ds-banner{width:100%;height:var(--dimension-space-100);flex-shrink:0;overflow:hidden;border-bottom:var(--dimension-stroke-width-015) solid var(--color-border-primary)}.banner-header.sc-ds-banner{width:100%;height:100%;background:repeating-linear-gradient( -45deg, var(--banner-content), var(--banner-content) var(--dimension-size-100), transparent var(--dimension-size-100), transparent var(--dimension-size-200) )}.banner-body.sc-ds-banner{padding:var(--dimension-space-075);min-height:var(--dimension-size-400);display:flex;align-items:flex-start;gap:var(--dimension-space-075)}.banner-message.sc-ds-banner{color:var(--banner-content);line-height:var(--typography-lineheight-md);display:block;flex:1;min-width:0}.banner-dismiss.sc-ds-banner{background:none;border:none;margin:0;padding:var(--dimension-space-025);color:var(--banner-content);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:var(--dimension-radius-050);position:relative;font-size:18px;line-height:1}.banner-dismiss.sc-ds-banner::before{content:'';position:absolute;inset:0;border-radius:inherit;background-color:transparent;transition:var(--effect-transition-interaction-background-short-2, background-color var(--effect-motion-short-2));pointer-events:none}.banner-dismiss.sc-ds-banner:hover::before{background-color:var(--color-interaction-hover)}.banner-dismiss.sc-ds-banner:active::before{background-color:var(--color-interaction-pressed)}.banner-dismiss.sc-ds-banner:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-stroke-width-015)}.floating-position.sc-ds-banner{position:fixed;top:var(--dimension-space-200);left:50%;transform:translateX(-50%);pointer-events:none}.floating-toast.sc-ds-banner{pointer-events:auto;animation:bannerFadeIn var(--effect-motion-short-2, 150ms) forwards}.floating-toast--closing.sc-ds-banner{animation:bannerFadeOut var(--effect-motion-short-3, 200ms) forwards}@keyframes bannerFadeIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}@keyframes bannerFadeOut{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-4px)}}`;const o=200;const d=4e3;const l=e(class e extends s{constructor(e){super();if(e!==false){this.__registerHost()}this.dsDismiss=n(this,"dsDismiss");this.intent="neutral";this.contrast="medium";this.message="";this.header=false;this.floating=false;this.showDismiss=false;this.dismissLabel="Dismiss";this.closing=false;this.dismissTimer=null;this.closeTimer=null}componentDidLoad(){if(this.floating&&this.message)this.scheduleDismiss()}onMessageChange(e){if(this.floating&&e){this.closing=false;this.scheduleDismiss()}}disconnectedCallback(){this.clearTimers()}clearTimers(){if(this.dismissTimer){clearTimeout(this.dismissTimer);this.dismissTimer=null}if(this.closeTimer){clearTimeout(this.closeTimer);this.closeTimer=null}}scheduleDismiss(){this.clearTimers();this.dismissTimer=setTimeout((()=>{this.dismissTimer=null;this.beginClose()}),d)}beginClose(){this.clearTimers();if(this.floating){this.closing=true;this.closeTimer=setTimeout((()=>{this.closing=false;this.closeTimer=null;this.dsDismiss.emit()}),o)}else{this.dsDismiss.emit()}}getContentColor(){if(this.contrast==="bold")return"var(--color-foreground-on-bold-background-primary)";const e=this.contrast==="faint"?"bold":this.contrast==="medium"?"strong":"medium";return`var(--color-foreground-${e}-${this.intent})`}getBg(){return`var(--color-background-${this.contrast}-${this.intent})`}getElevation(){return this.floating?"var(--effect-elevation-elevated-floating)":"var(--effect-elevation-elevated-sm)"}render(){const e=this.getContentColor();const s=this.intent==="negative";const n=t("div",{class:{"banner-wrapper":true},style:{"--banner-content":e},role:s?"alert":"status","aria-live":s?undefined:"polite"},t("div",{class:"banner-surface",style:{backgroundColor:this.getBg(),boxShadow:this.getElevation()}},this.header&&t("div",{class:"banner-header-surface"},t("div",{class:"banner-header"})),t("div",{class:"banner-body"},t("span",{class:"text-body-medium banner-message"},this.message),this.showDismiss&&t("button",{type:"button",class:"banner-dismiss",onClick:()=>this.beginClose(),"aria-label":this.dismissLabel},"×"))));if(this.floating){return t(i,{style:{display:"contents"}},t("div",{class:"floating-position",style:{zIndex:"9998"}},t("div",{class:{"floating-toast":true,"floating-toast--closing":this.closing}},n)))}return t(i,{style:{display:"contents"}},n)}static get watchers(){return{message:[{onMessageChange:0}]}}static get style(){return r()}},[2,"ds-banner",{intent:[1],contrast:[1],message:[1],header:[4],floating:[4],showDismiss:[4,"show-dismiss"],dismissLabel:[1,"dismiss-label"],closing:[32]},undefined,{message:[{onMessageChange:0}]}]);function c(){if(typeof customElements==="undefined"){return}const e=["ds-banner"];e.forEach((e=>{switch(e){case"ds-banner":if(!customElements.get(a(e))){customElements.define(a(e),l)}break}}))}c();const h=l;const f=c;export{h as DsBanner,f as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-banner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["bannerCss","FADE_OUT_MS","AUTO_DISMISS_MS","Banner","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","intent","contrast","message","header","floating","showDismiss","dismissLabel","closing","dismissTimer","closeTimer","componentDidLoad","scheduleDismiss","onMessageChange","newVal","disconnectedCallback","clearTimers","clearTimeout","setTimeout","beginClose","dsDismiss","emit","getContentColor","c","getBg","getElevation","render","contentColor","isAssertive","bannerEl","h","class","style","role","undefined","backgroundColor","boxShadow","type","onClick","Host","display","zIndex"],"sources":["src/wc/components/Banner/Banner.css?tag=ds-banner&encapsulation=scoped","src/wc/components/Banner/Banner.tsx"],"sourcesContent":[".banner-surface {\n position: relative;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-radius: var(--dimension-radius-075);\n}\n\n.banner-header-surface {\n width: 100%;\n height: var(--dimension-space-100);\n flex-shrink: 0;\n overflow: hidden;\n border-bottom: var(--dimension-stroke-width-015) solid var(--color-border-primary);\n}\n\n.banner-header {\n width: 100%;\n height: 100%;\n background: repeating-linear-gradient(\n -45deg,\n var(--banner-content),\n var(--banner-content) var(--dimension-size-100),\n transparent var(--dimension-size-100),\n transparent var(--dimension-size-200)\n );\n}\n\n.banner-body {\n padding: var(--dimension-space-075);\n min-height: var(--dimension-size-400);\n display: flex;\n align-items: flex-start;\n gap: var(--dimension-space-075);\n}\n\n.banner-message {\n color: var(--banner-content);\n line-height: var(--typography-lineheight-md);\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.banner-dismiss {\n background: none;\n border: none;\n margin: 0;\n padding: var(--dimension-space-025);\n color: var(--banner-content);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: var(--dimension-radius-050);\n position: relative;\n font-size: 18px;\n line-height: 1;\n}\n\n.banner-dismiss::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: transparent;\n transition: var(--effect-transition-interaction-background-short-2, background-color var(--effect-motion-short-2));\n pointer-events: none;\n}\n\n.banner-dismiss:hover::before { background-color: var(--color-interaction-hover); }\n.banner-dismiss:active::before { background-color: var(--color-interaction-pressed); }\n\n.banner-dismiss:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-stroke-width-015);\n}\n\n/* ─── Floating ──────────────────────────────────────────────────────────────── */\n\n.floating-position {\n position: fixed;\n top: var(--dimension-space-200);\n left: 50%;\n transform: translateX(-50%);\n pointer-events: none;\n}\n\n.floating-toast {\n pointer-events: auto;\n animation: bannerFadeIn var(--effect-motion-short-2, 150ms) forwards;\n}\n\n.floating-toast--closing {\n animation: bannerFadeOut var(--effect-motion-short-3, 200ms) forwards;\n}\n\n@keyframes bannerFadeIn {\n from { opacity: 0; transform: translateY(-8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n@keyframes bannerFadeOut {\n from { opacity: 1; transform: translateY(0); }\n to { opacity: 0; transform: translateY(-4px); }\n}\n","import { Component, Prop, State, Event, EventEmitter, Watch, h, Host } from '@stencil/core';\n\nexport type BannerIntent =\n | 'brand' | 'positive' | 'negative' | 'warning' | 'caution'\n | 'ai' | 'neutral' | 'walkthrough' | 'guide';\n\nexport type BannerContrast = 'faint' | 'medium' | 'bold' | 'strong';\n\nconst FADE_OUT_MS = 200;\nconst AUTO_DISMISS_MS = 4000;\n\n@Component({\n tag: 'ds-banner',\n styleUrl: 'Banner.css',\n scoped: true,\n})\nexport class Banner {\n @Prop() intent: BannerIntent = 'neutral';\n @Prop() contrast: BannerContrast = 'medium';\n @Prop() message: string = '';\n /** Renders the diagonal-stripe accent bar above the body. */\n @Prop() header: boolean = false;\n /** Renders at a fixed position (centered top) and auto-dismisses after 4 s. */\n @Prop() floating: boolean = false;\n @Prop() showDismiss: boolean = false;\n @Prop() dismissLabel: string = 'Dismiss';\n\n @State() private closing: boolean = false;\n\n @Event() dsDismiss!: EventEmitter<void>;\n\n private dismissTimer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n\n componentDidLoad() {\n if (this.floating && this.message) this.scheduleDismiss();\n }\n\n @Watch('message')\n onMessageChange(newVal: string) {\n if (this.floating && newVal) {\n this.closing = false;\n this.scheduleDismiss();\n }\n }\n\n disconnectedCallback() {\n this.clearTimers();\n }\n\n private clearTimers() {\n if (this.dismissTimer) { clearTimeout(this.dismissTimer); this.dismissTimer = null; }\n if (this.closeTimer) { clearTimeout(this.closeTimer); this.closeTimer = null; }\n }\n\n private scheduleDismiss() {\n this.clearTimers();\n this.dismissTimer = setTimeout(() => {\n this.dismissTimer = null;\n this.beginClose();\n }, AUTO_DISMISS_MS);\n }\n\n private beginClose() {\n this.clearTimers();\n if (this.floating) {\n this.closing = true;\n this.closeTimer = setTimeout(() => {\n this.closing = false;\n this.closeTimer = null;\n this.dsDismiss.emit();\n }, FADE_OUT_MS);\n } else {\n this.dsDismiss.emit();\n }\n }\n\n private getContentColor(): string {\n if (this.contrast === 'bold') return 'var(--color-foreground-on-bold-background-primary)';\n const c = this.contrast === 'faint' ? 'bold' : this.contrast === 'medium' ? 'strong' : 'medium';\n return `var(--color-foreground-${c}-${this.intent})`;\n }\n\n private getBg(): string {\n return `var(--color-background-${this.contrast}-${this.intent})`;\n }\n\n private getElevation(): string {\n return this.floating\n ? 'var(--effect-elevation-elevated-floating
|
|
1
|
+
{"version":3,"names":["bannerCss","FADE_OUT_MS","AUTO_DISMISS_MS","Banner","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","intent","contrast","message","header","floating","showDismiss","dismissLabel","closing","dismissTimer","closeTimer","componentDidLoad","scheduleDismiss","onMessageChange","newVal","disconnectedCallback","clearTimers","clearTimeout","setTimeout","beginClose","dsDismiss","emit","getContentColor","c","getBg","getElevation","render","contentColor","isAssertive","bannerEl","h","class","style","role","undefined","backgroundColor","boxShadow","type","onClick","Host","display","zIndex"],"sources":["src/wc/components/Banner/Banner.css?tag=ds-banner&encapsulation=scoped","src/wc/components/Banner/Banner.tsx"],"sourcesContent":[".banner-surface {\n position: relative;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n border-radius: var(--dimension-radius-075);\n}\n\n.banner-header-surface {\n width: 100%;\n height: var(--dimension-space-100);\n flex-shrink: 0;\n overflow: hidden;\n border-bottom: var(--dimension-stroke-width-015) solid var(--color-border-primary);\n}\n\n.banner-header {\n width: 100%;\n height: 100%;\n background: repeating-linear-gradient(\n -45deg,\n var(--banner-content),\n var(--banner-content) var(--dimension-size-100),\n transparent var(--dimension-size-100),\n transparent var(--dimension-size-200)\n );\n}\n\n.banner-body {\n padding: var(--dimension-space-075);\n min-height: var(--dimension-size-400);\n display: flex;\n align-items: flex-start;\n gap: var(--dimension-space-075);\n}\n\n.banner-message {\n color: var(--banner-content);\n line-height: var(--typography-lineheight-md);\n display: block;\n flex: 1;\n min-width: 0;\n}\n\n.banner-dismiss {\n background: none;\n border: none;\n margin: 0;\n padding: var(--dimension-space-025);\n color: var(--banner-content);\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: var(--dimension-radius-050);\n position: relative;\n font-size: 18px;\n line-height: 1;\n}\n\n.banner-dismiss::before {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: inherit;\n background-color: transparent;\n transition: var(--effect-transition-interaction-background-short-2, background-color var(--effect-motion-short-2));\n pointer-events: none;\n}\n\n.banner-dismiss:hover::before { background-color: var(--color-interaction-hover); }\n.banner-dismiss:active::before { background-color: var(--color-interaction-pressed); }\n\n.banner-dismiss:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-stroke-width-015);\n}\n\n/* ─── Floating ──────────────────────────────────────────────────────────────── */\n\n.floating-position {\n position: fixed;\n top: var(--dimension-space-200);\n left: 50%;\n transform: translateX(-50%);\n pointer-events: none;\n}\n\n.floating-toast {\n pointer-events: auto;\n animation: bannerFadeIn var(--effect-motion-short-2, 150ms) forwards;\n}\n\n.floating-toast--closing {\n animation: bannerFadeOut var(--effect-motion-short-3, 200ms) forwards;\n}\n\n@keyframes bannerFadeIn {\n from { opacity: 0; transform: translateY(-8px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n@keyframes bannerFadeOut {\n from { opacity: 1; transform: translateY(0); }\n to { opacity: 0; transform: translateY(-4px); }\n}\n","import { Component, Prop, State, Event, EventEmitter, Watch, h, Host } from '@stencil/core';\n\nexport type BannerIntent =\n | 'brand' | 'positive' | 'negative' | 'warning' | 'caution'\n | 'ai' | 'neutral' | 'walkthrough' | 'guide';\n\nexport type BannerContrast = 'faint' | 'medium' | 'bold' | 'strong';\n\nconst FADE_OUT_MS = 200;\nconst AUTO_DISMISS_MS = 4000;\n\n@Component({\n tag: 'ds-banner',\n styleUrl: 'Banner.css',\n scoped: true,\n})\nexport class Banner {\n @Prop() intent: BannerIntent = 'neutral';\n @Prop() contrast: BannerContrast = 'medium';\n @Prop() message: string = '';\n /** Renders the diagonal-stripe accent bar above the body. */\n @Prop() header: boolean = false;\n /** Renders at a fixed position (centered top) and auto-dismisses after 4 s. */\n @Prop() floating: boolean = false;\n @Prop() showDismiss: boolean = false;\n @Prop() dismissLabel: string = 'Dismiss';\n\n @State() private closing: boolean = false;\n\n @Event() dsDismiss!: EventEmitter<void>;\n\n private dismissTimer: ReturnType<typeof setTimeout> | null = null;\n private closeTimer: ReturnType<typeof setTimeout> | null = null;\n\n componentDidLoad() {\n if (this.floating && this.message) this.scheduleDismiss();\n }\n\n @Watch('message')\n onMessageChange(newVal: string) {\n if (this.floating && newVal) {\n this.closing = false;\n this.scheduleDismiss();\n }\n }\n\n disconnectedCallback() {\n this.clearTimers();\n }\n\n private clearTimers() {\n if (this.dismissTimer) { clearTimeout(this.dismissTimer); this.dismissTimer = null; }\n if (this.closeTimer) { clearTimeout(this.closeTimer); this.closeTimer = null; }\n }\n\n private scheduleDismiss() {\n this.clearTimers();\n this.dismissTimer = setTimeout(() => {\n this.dismissTimer = null;\n this.beginClose();\n }, AUTO_DISMISS_MS);\n }\n\n private beginClose() {\n this.clearTimers();\n if (this.floating) {\n this.closing = true;\n this.closeTimer = setTimeout(() => {\n this.closing = false;\n this.closeTimer = null;\n this.dsDismiss.emit();\n }, FADE_OUT_MS);\n } else {\n this.dsDismiss.emit();\n }\n }\n\n private getContentColor(): string {\n if (this.contrast === 'bold') return 'var(--color-foreground-on-bold-background-primary)';\n const c = this.contrast === 'faint' ? 'bold' : this.contrast === 'medium' ? 'strong' : 'medium';\n return `var(--color-foreground-${c}-${this.intent})`;\n }\n\n private getBg(): string {\n return `var(--color-background-${this.contrast}-${this.intent})`;\n }\n\n private getElevation(): string {\n return this.floating\n ? 'var(--effect-elevation-elevated-floating)'\n : 'var(--effect-elevation-elevated-sm)';\n }\n\n render() {\n const contentColor = this.getContentColor();\n const isAssertive = this.intent === 'negative';\n\n const bannerEl = (\n <div\n class={{ 'banner-wrapper': true }}\n style={{ '--banner-content': contentColor } as { [key: string]: string }}\n role={isAssertive ? 'alert' : 'status'}\n aria-live={isAssertive ? undefined : 'polite'}\n >\n <div\n class=\"banner-surface\"\n style={{\n backgroundColor: this.getBg(),\n boxShadow: this.getElevation(),\n }}\n >\n {this.header && (\n <div class=\"banner-header-surface\">\n <div class=\"banner-header\" />\n </div>\n )}\n <div class=\"banner-body\">\n <span class=\"text-body-medium banner-message\">{this.message}</span>\n {this.showDismiss && (\n <button\n type=\"button\"\n class=\"banner-dismiss\"\n onClick={() => this.beginClose()}\n aria-label={this.dismissLabel}\n >\n ×\n </button>\n )}\n </div>\n </div>\n </div>\n );\n\n if (this.floating) {\n return (\n <Host style={{ display: 'contents' }}>\n <div class=\"floating-position\" style={{ zIndex: '9998' }}>\n <div class={{ 'floating-toast': true, 'floating-toast--closing': this.closing }}>\n {bannerEl}\n </div>\n </div>\n </Host>\n );\n }\n\n return <Host style={{ display: 'contents' }}>{bannerEl}</Host>;\n }\n}\n"],"mappings":"kEAAA,MAAMA,EAAY,IAAM,41ECQxB,MAAMC,EAAc,IACpB,MAAMC,EAAkB,I,MAOXC,EAAMC,EAAA,MAAAD,UAAAE,EALnB,WAAAC,CAAAC,G,+EAMUC,KAAAC,OAAuB,UACvBD,KAAAE,SAA2B,SAC3BF,KAAAG,QAAkB,GAElBH,KAAAI,OAAkB,MAElBJ,KAAAK,SAAoB,MACpBL,KAAAM,YAAuB,MACvBN,KAAAO,aAAuB,UAEdP,KAAAQ,QAAmB,MAI5BR,KAAAS,aAAqD,KACrDT,KAAAU,WAAmD,IAmH5D,CAjHC,gBAAAC,GACE,GAAIX,KAAKK,UAAYL,KAAKG,QAASH,KAAKY,iB,CAI1C,eAAAC,CAAgBC,GACd,GAAId,KAAKK,UAAYS,EAAQ,CAC3Bd,KAAKQ,QAAU,MACfR,KAAKY,iB,EAIT,oBAAAG,GACEf,KAAKgB,a,CAGC,WAAAA,GACN,GAAIhB,KAAKS,aAAc,CAAEQ,aAAajB,KAAKS,cAAeT,KAAKS,aAAe,I,CAC9E,GAAIT,KAAKU,WAAc,CAAEO,aAAajB,KAAKU,YAAeV,KAAKU,WAAa,I,EAGtE,eAAAE,GACNZ,KAAKgB,cACLhB,KAAKS,aAAeS,YAAW,KAC7BlB,KAAKS,aAAe,KACpBT,KAAKmB,YAAY,GAChBzB,E,CAGG,UAAAyB,GACNnB,KAAKgB,cACL,GAAIhB,KAAKK,SAAU,CACjBL,KAAKQ,QAAU,KACfR,KAAKU,WAAaQ,YAAW,KAC3BlB,KAAKQ,QAAU,MACfR,KAAKU,WAAa,KAClBV,KAAKoB,UAAUC,MAAM,GACpB5B,E,KACE,CACLO,KAAKoB,UAAUC,M,EAIX,eAAAC,GACN,GAAItB,KAAKE,WAAa,OAAQ,MAAO,qDACrC,MAAMqB,EAAIvB,KAAKE,WAAa,QAAU,OAASF,KAAKE,WAAa,SAAW,SAAW,SACvF,MAAO,0BAA0BqB,KAAKvB,KAAKC,S,CAGrC,KAAAuB,GACN,MAAO,0BAA0BxB,KAAKE,YAAYF,KAAKC,S,CAGjD,YAAAwB,GACN,OAAOzB,KAAKK,SACR,4CACA,qC,CAGN,MAAAqB,GACE,MAAMC,EAAe3B,KAAKsB,kBAC1B,MAAMM,EAAc5B,KAAKC,SAAW,WAEpC,MAAM4B,EACJC,EAAA,OACEC,MAAO,CAAE,iBAAkB,MAC3BC,MAAO,CAAE,mBAAoBL,GAC7BM,KAAML,EAAc,QAAU,SAAQ,YAC3BA,EAAcM,UAAY,UAErCJ,EAAA,OACEC,MAAM,iBACNC,MAAO,CACLG,gBAAiBnC,KAAKwB,QACtBY,UAAWpC,KAAKyB,iBAGjBzB,KAAKI,QACJ0B,EAAA,OAAKC,MAAM,yBACTD,EAAA,OAAKC,MAAM,mBAGfD,EAAA,OAAKC,MAAM,eACTD,EAAA,QAAMC,MAAM,mCAAmC/B,KAAKG,SACnDH,KAAKM,aACJwB,EAAA,UACEO,KAAK,SACLN,MAAM,iBACNO,QAAS,IAAMtC,KAAKmB,aAAY,aACpBnB,KAAKO,cAAY,QAUzC,GAAIP,KAAKK,SAAU,CACjB,OACEyB,EAACS,EAAI,CAACP,MAAO,CAAEQ,QAAS,aACtBV,EAAA,OAAKC,MAAM,oBAAoBC,MAAO,CAAES,OAAQ,SAC9CX,EAAA,OAAKC,MAAO,CAAE,iBAAkB,KAAM,0BAA2B/B,KAAKQ,UACnEqB,I,CAOX,OAAOC,EAACS,EAAI,CAACP,MAAO,CAAEQ,QAAS,aAAeX,E","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{B as o,d as s}from"./p-
|
|
1
|
+
import{B as o,d as s}from"./p-qfvbc9w-.js";const t=o;const c=s;export{t as DsBarNavAction,c as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-bar-nav-action.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as t,c as a,h as s,a as i,t as n}from"./index.js";import{g as r,i as o}from"./p-BQq26pt9.js";import{d as h}from"./p-Vwlmhl4E.js";import{d}from"./p-H89PzqGU.js";import{d as c}from"./p-CpbnmEu1.js";import{d as b}from"./p-CMyQsk0K.js";function l(e,t,a){if(!e||!t){return{value:"",hideTabs:false}}if(e!==t&&!e.startsWith(`${t}/`)){return{value:"",hideTabs:false}}const s=e.slice(t.length);const i=s.startsWith("/")?s.slice(1).split("/")[0]:"";const n=r(a);if(!i){return{value:n[0]?.id??"",hideTabs:false}}const o=n.find((e=>e.id===i));if(o){return{value:o.id,hideTabs:false}}return{value:"",hideTabs:true}}function v(e,t,a,s,i,n){const r=a?u(a,[]):t??[];const o=n?u(n,[]):i??[];return e.length===0&&r.length>0||s.length===0&&o.length>0}function u(e,t){if(Array.isArray(e))return e;if(typeof e==="string"&&e!==""){try{const a=JSON.parse(e);return Array.isArray(a)?a:t}catch{return t}}return t}function f(e,t){if(!e)return null;const a=e.shadowRoot??e;return a.querySelector(t)}function g(e){return f(e,'[role="tablist"]')}function p(e,t){const a=[];let s=[];for(const i of e){if(o(i)){if(s.length>0){a.push({items:s});s=[]}continue}s.push({label:i.label,value:i.id,isSelected:i.id===t,isInactive:i.disabled})}if(s.length>0){a.push({items:s})}return a}function m(e,t){const a=r(e);return a.find((e=>e.id===t))??a[0]}function _(e,t){return m(e,t)?.label??"Tabs"}function k(e,t,a,s=2){const i=e-t;if(a){return i>-s}return i>s}const y=()=>`.sc-ds-bar-nav-h{display:block}.bar-nav.sc-ds-bar-nav{display:flex;align-items:center;position:relative;height:var(--dimension-size-600);padding:var(--dimension-space-100);gap:var(--dimension-space-100);box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012) solid var(--color-border-tertiary)}.bg-primary.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-primary);background-color:var(--_bar-nav-bg)}.bg-secondary.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-secondary);background-color:var(--_bar-nav-bg)}.bg-transparent.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-primary);background-color:transparent}.bg-translucent.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-translucent);background-color:var(--_bar-nav-bg);backdrop-filter:blur(var(--effect-blur-md));-webkit-backdrop-filter:blur(var(--effect-blur-md))}.bar-nav--tabs-collapsed.sc-ds-bar-nav{display:flex;gap:0;align-items:center}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger.sc-ds-bar-nav{flex:0 1 auto;min-width:0;max-width:100%;width:auto;overflow:hidden}.bar-nav__between.sc-ds-bar-nav{flex:1 1 0%;min-width:var(--dimension-space-100)}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label.sc-ds-bar-nav{flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:block;flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__actions.sc-ds-bar-nav{flex:0 0 auto;margin-left:0}.bar-nav__left.sc-ds-bar-nav{position:relative;flex:1 1 0%;min-width:0;width:0;display:flex;align-items:center}.bar-nav__left.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{flex:1;min-width:0}.bar-nav__tabs-probe.sc-ds-bar-nav{position:absolute;left:0;top:0;visibility:hidden;pointer-events:none;overflow:visible;width:max-content;max-width:none;z-index:-1}.bar-nav__tabs-probe.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{width:max-content}.bar-nav__tabs-visible.sc-ds-bar-nav{width:100%;min-width:0}.bar-nav__tabs-pending.sc-ds-bar-nav{flex:1;min-width:0;height:var(--dimension-size-400);visibility:hidden;pointer-events:none}.bar-nav__tab-trigger.sc-ds-bar-nav{all:unset;box-sizing:border-box;display:inline-flex;align-items:center;gap:var(--dimension-space-050);flex:0 1 auto;min-width:0;width:max-content;max-width:100%;padding:var(--dimension-space-075);background-color:transparent;border-radius:var(--dimension-radius-025);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--color-foreground-primary);position:relative;transition:color var(--effect-motion-short-2);height:var(--dimension-size-400);--_hover-bg:var(--color-interaction-hover);--_pressed-bg:var(--color-interaction-pressed);--_dot:var(--color-foreground-bold-brand);--_dot-ring:var(--color-background-secondary)}.bar-nav__tab-trigger.sc-ds-bar-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025);background:transparent;pointer-events:none;transition:none;z-index:2}.bar-nav__tab-trigger.sc-ds-bar-nav:hover::after{background:var(--_hover-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:active::after{background:var(--_pressed-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-space-025)}.bar-nav__tab-trigger--open.sc-ds-bar-nav::after{background:var(--_hover-bg)}.bar-nav__tab-trigger-label.sc-ds-bar-nav{position:relative;display:inline-flex;align-items:center;flex:0 1 auto;min-width:0;max-width:100%;padding:0 var(--dimension-space-025);overflow:hidden;--_fade-right:var(--dimension-space-025);z-index:1}.bar-nav__tab-trigger-label--truncated.sc-ds-bar-nav::after{content:'';position:absolute;top:0;right:var(--_fade-right);bottom:0;width:var(--dimension-size-400);background:linear-gradient(to right, transparent, var(--_bar-nav-bg));pointer-events:none;z-index:1}.bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:inline-block;max-width:100%;box-sizing:border-box;white-space:nowrap;overflow:hidden;vertical-align:bottom}.bar-nav__tab-trigger-label-text--truncated.sc-ds-bar-nav{-webkit-mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%}.bar-nav__tab-trigger-label--dot.sc-ds-bar-nav{padding-right:calc(var(--dimension-space-025) + var(--dimension-space-050));--_fade-right:calc(var(--dimension-space-025) + var(--dimension-space-050))}.bar-nav__tab-trigger-dot.sc-ds-bar-nav{position:absolute;top:0;right:0;width:var(--dimension-size-075, calc(var(--dimension-size-base) * 3 / 4));height:var(--dimension-size-075, calc(var(--dimension-size-base) * 3 / 4));border-radius:var(--dimension-radius-half);background:var(--_dot);box-shadow:0 0 0 var(--dimension-stroke-width-018) var(--_dot-ring);pointer-events:none;z-index:1}.bar-nav__tab-trigger-chevron.sc-ds-bar-nav{position:relative;flex-shrink:0;z-index:1}.bar-nav__heading.sc-ds-bar-nav{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);color:var(--color-foreground-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bar-nav__actions.sc-ds-bar-nav{display:flex;align-items:center;gap:var(--dimension-space-050);flex:0 0 auto;margin-left:auto}`;const w=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.dsTabChange=a(this,"dsTabChange");this.dsActionChange=a(this,"dsActionChange");this.tabs=[];this.tabsJson="";this.value="";this.actions=[];this.actionsJson="";this.background="secondary";this.basePath="";this.currentUrl="";this.resolvedTabs=[];this.resolvedActions=[];this.urlDerivedValue="";this.hideTabsForDetailRoute=false;this.tabsCollapsed=false;this.menuOpen=false;this.tabLayoutCommitted=false;this.triggerLabelTruncated=false;this.headerEl=null;this.triggerEl=null;this.triggerLabelTextEl=null;this.triggerLabelObserver=null;this.menuEl=null;this.visibleTabGroupEl=null;this.probeTabGroupEl=null;this.resizeObserver=null;this.overflowCheckScheduled=false;this.intrinsicWidthRetryCount=0}get effectiveValue(){if(this.currentUrl&&this.basePath){return this.urlDerivedValue}return this.value}get activeTabLabel(){return _(this.resolvedTabs,this.effectiveValue)}get activeTabHasDot(){return!!m(this.resolvedTabs,this.effectiveValue)?.dot}onPropsChange(){this.resolvedTabs=this.tabsJson?u(this.tabsJson,[]):this.tabs??[];this.resolvedActions=this.actionsJson?u(this.actionsJson,[]):this.actions??[];this.syncValueFromUrl();this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}onUrlChange(){this.syncValueFromUrl();this.scheduleOverflowCheck()}onSelectionChange(){this.syncMenuSections();this.scheduleOverflowCheck()}onMenuOpenChange(e){if(this.menuEl){this.menuEl.open=e}}onTabsCollapsedChange(e,t){if(!e){this.menuOpen=false;this.menuEl=null;this.triggerLabelTruncated=false;this.syncTriggerLabelObserver()}this.scheduleOverflowCheck();if(e){requestAnimationFrame((()=>{this.scheduleOverflowCheck();this.syncTriggerLabelObserver()}))}if(e||t===undefined||t===e)return;requestAnimationFrame((()=>this.scheduleOverflowCheck()));queueMicrotask((()=>this.focusVisibleSelectedTab()))}componentWillLoad(){this.onPropsChange()}componentDidLoad(){this.syncHostPropsIfNeeded();this.scheduleDeferredHostPropSync();this.setupOverflowObserver();this.scheduleOverflowCheck()}componentDidRender(){this.scheduleOverflowCheck();this.syncMenuAnchor();if(this.tabsCollapsed){this.updateTriggerLabelTruncation()}}disconnectedCallback(){this.resizeObserver?.disconnect();this.resizeObserver=null;this.syncTriggerLabelObserver(true)}syncHostPropsIfNeeded(){if(v(this.resolvedTabs,this.tabs,this.tabsJson,this.resolvedActions,this.actions,this.actionsJson)){this.onPropsChange()}else if(this.currentUrl&&this.basePath){this.syncValueFromUrl()}}scheduleDeferredHostPropSync(){let t=e.HOST_PROP_SYNC_BUDGET;const a=()=>{this.syncHostPropsIfNeeded();if(--t>0){requestAnimationFrame(a)}};queueMicrotask(a)}setupOverflowObserver(){if(typeof ResizeObserver==="undefined"||!this.headerEl)return;this.resizeObserver?.disconnect();this.resizeObserver=new ResizeObserver((()=>this.scheduleOverflowCheck()));this.resizeObserver.observe(this.headerEl)}scheduleOverflowCheck(){if(this.overflowCheckScheduled)return;this.overflowCheckScheduled=true;requestAnimationFrame((()=>{this.overflowCheckScheduled=false;this.updateTabsCollapsed();this.updateTriggerLabelTruncation()}))}syncTriggerLabelObserver(e=false){this.triggerLabelObserver?.disconnect();this.triggerLabelObserver=null;if(e||!this.tabsCollapsed||!this.triggerLabelTextEl){return}this.updateTriggerLabelTruncation();if(typeof ResizeObserver==="undefined")return;this.triggerLabelObserver=new ResizeObserver((()=>this.updateTriggerLabelTruncation()));this.triggerLabelObserver.observe(this.triggerLabelTextEl);if(this.triggerEl){this.triggerLabelObserver.observe(this.triggerEl)}}updateTriggerLabelTruncation(){const e=this.triggerLabelTextEl;if(!e||!this.tabsCollapsed){if(this.triggerLabelTruncated){this.triggerLabelTruncated=false}return}const t=e.scrollWidth>e.clientWidth+1;if(t!==this.triggerLabelTruncated){this.triggerLabelTruncated=t}}getLeftZoneAvailableWidth(){if(!this.headerEl)return 0;const e=getComputedStyle(this.headerEl);const t=parseFloat(e.columnGap||e.gap||"0")||0;const a=this.headerEl.querySelector(".bar-nav__actions");const s=a?.offsetWidth??0;const i=(parseFloat(e.paddingLeft)||0)+(parseFloat(e.paddingRight)||0);const n=this.tabsCollapsed?parseFloat(getComputedStyle(this.headerEl).getPropertyValue("--dimension-space-100").trim())||8:a?t:0;const r=this.headerEl.clientWidth-i-s-n;return Math.max(0,r)}getTabsIntrinsicWidth(){const e=g(this.probeTabGroupEl);return e?.scrollWidth??0}scheduleIntrinsicWidthRetry(){if(this.intrinsicWidthRetryCount>=e.INTRINSIC_WIDTH_RETRY_MAX)return;this.intrinsicWidthRetryCount++;requestAnimationFrame((()=>this.scheduleOverflowCheck()))}updateTabsCollapsed(){if(!this.headerEl||this.resolvedTabs.length===0||this.hideTabsForDetailRoute){if(this.tabsCollapsed){this.tabsCollapsed=false;this.menuOpen=false}this.intrinsicWidthRetryCount=0;return}const e=this.getTabsIntrinsicWidth();if(e===0){this.scheduleIntrinsicWidthRetry();return}this.intrinsicWidthRetryCount=0;const t=k(e,this.getLeftZoneAvailableWidth(),this.tabsCollapsed);if(t!==this.tabsCollapsed){this.tabsCollapsed=t;if(!t){this.menuOpen=false}}}syncMenuAnchor(){if(!this.menuEl||!this.triggerEl||!this.tabsCollapsed)return;this.menuEl.anchor=this.triggerEl;this.syncMenuSections()}handleMenuSelect(e){const t=e.detail;if(t?.value!==undefined){this.selectTab(String(t.value))}this.menuOpen=false}handleMenuClose(){this.menuOpen=false}syncMenuSections(){if(!this.menuEl)return;this.menuEl.sections=p(this.resolvedTabs,this.effectiveValue)}syncValueFromUrl(){if(!this.currentUrl||!this.basePath){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}const{value:e,hideTabs:t}=l(this.currentUrl,this.basePath,this.resolvedTabs);this.urlDerivedValue=e;this.hideTabsForDetailRoute=t}selectTab(e){this.value=e;this.dsTabChange.emit(e)}focusVisibleSelectedTab(){const e=f(this.visibleTabGroupEl,`[data-tab-id="${this.effectiveValue}"]`);e?.focus({preventScroll:true})}handleTabChange(e){this.selectTab(e.detail)}handleActionChange(e,t){const a=t.detail;this.dsActionChange.emit({id:e,selected:a})}toggleTabMenu(){if(this.menuOpen){this.menuOpen=false;return}if(this.menuEl&&this.triggerEl){this.menuEl.anchor=this.triggerEl;this.menuEl.minWidth=`${this.triggerEl.offsetWidth}px`;this.syncMenuSections()}this.menuOpen=true}handleTriggerKeyDown(e){if(!this.tabsCollapsed)return;if(!this.menuOpen){if(e.key==="ArrowDown"||e.key==="ArrowUp"||e.key==="Enter"||e.key===" "){e.preventDefault();this.toggleTabMenu()}return}if(e.key==="Escape"){e.preventDefault();this.menuOpen=false;this.triggerEl?.focus()}}render(){const e=this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute;const t={};const a=t[this.background];return s(i,{key:"6a9d06038e714910ee3375976014d5afe659e2c6"},s("header",{key:"3c4d7c65013ce9da9c4a1d9588446bfdbdf1bcb4",class:{"bar-nav":true,[`bg-${this.background}`]:true,"bar-nav--tabs-collapsed":e&&this.tabsCollapsed},ref:e=>{this.headerEl=e;if(e&&!this.resizeObserver){this.setupOverflowObserver()}}},e&&s("div",{key:"36f1e91251e9989b80a3bb281f2847158759cb4d",class:"bar-nav__tabs-probe","aria-hidden":"true",inert:true},s("ds-tab-group-nav",{key:"a24197e86bdde94923267d19c423886dfd363de3",ref:e=>{this.probeTabGroupEl=e??null;if(e){this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}},tabs:this.resolvedTabs,value:this.effectiveValue})),e&&!this.tabsCollapsed&&s("div",{key:"7bc48ddd515153663513ab7c16609fa94183816f",class:"bar-nav__left"},s("ds-tab-group-nav",{key:"f80f1d9cc146da03f90585e4649d2705fe2c705b",class:"bar-nav__tabs-visible",ref:e=>{this.visibleTabGroupEl=e??null},tabs:this.resolvedTabs,value:this.effectiveValue,onDsChange:e=>this.handleTabChange(e)})),!e&&this.heading&&s("span",{key:"19019151704839426b23973cbc5699bdc6b270ca",class:"bar-nav__heading text-body-medium-emphasis"},this.heading),e&&this.tabsCollapsed&&s("button",{key:"9aaafe90f6ac0978dc1f25515f7ee3cd7f6ad19d",type:"button",class:{"bar-nav__tab-trigger":true,"bar-nav__tab-trigger--open":this.menuOpen},ref:e=>{this.triggerEl=e},"aria-haspopup":"menu","aria-expanded":this.menuOpen,"aria-label":`${this.activeTabLabel} tabs`,onClick:()=>this.toggleTabMenu(),onKeyDown:e=>this.handleTriggerKeyDown(e)},s("span",{key:"0eaac771fba9716c6be8de618927129d74c2c92c",class:{"bar-nav__tab-trigger-label":true,"bar-nav__tab-trigger-label--dot":this.activeTabHasDot,"bar-nav__tab-trigger-label--truncated":this.triggerLabelTruncated}},s("span",{key:"79eada547183c260649ced329217039ed76c154c",class:{"bar-nav__tab-trigger-label-text":true,"bar-nav__tab-trigger-label-text--truncated":this.triggerLabelTruncated,"text-body-medium-emphasis":true},ref:e=>{const t=e??null;if(t===this.triggerLabelTextEl)return;this.triggerLabelTextEl=t;if(this.tabsCollapsed){this.syncTriggerLabelObserver()}}},this.activeTabLabel),this.activeTabHasDot&&s("span",{key:"877821b50c0c0652839a08d629e4eb45ccdfec2b",class:"bar-nav__tab-trigger-dot","aria-hidden":"true"})),s("ds-icon",{key:"077f931309ec4e8463e6dcba6b3c2499c4e66b4c",name:"ChevronDown",size:"md",color:"inherit",class:"bar-nav__tab-trigger-chevron"})),e&&this.tabsCollapsed&&this.resolvedActions.length>0&&s("div",{key:"d234ca16623cb045d28b387f764ad75517dd5a4b",class:"bar-nav__between","aria-hidden":"true"}),this.resolvedActions.length>0&&s("div",{key:"64965dacbcc2c7702b522577275c29fb29b654ed",class:"bar-nav__actions"},this.resolvedActions.map((e=>s("ds-bar-nav-action",{key:e.id,icon:e.icon,selected:e.selected??false,dot:e.dot??false,inactive:e.inactive,"aria-label":e.ariaLabel??e.id,background:a,onDsChange:t=>this.handleActionChange(e.id,t)}))))),e&&this.tabsCollapsed&&s("ds-menu",{key:"6e4d25047e852b7fd5eee80a98a2616fadbaea7b",ref:e=>{this.menuEl=e??null},open:this.menuOpen,sections:p(this.resolvedTabs,this.effectiveValue),side:"bottom",align:"start",onDsSelect:e=>this.handleMenuSelect(e),onDsClose:()=>this.handleMenuClose()}))}static get watchers(){return{tabs:[{onPropsChange:0}],tabsJson:[{onPropsChange:0}],actions:[{onPropsChange:0}],actionsJson:[{onPropsChange:0}],currentUrl:[{onUrlChange:0}],basePath:[{onUrlChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}}static get style(){return y()}},[2,"ds-bar-nav",{tabs:[16],tabsJson:[1,"tabs-json"],value:[1025],actions:[16],actionsJson:[1,"actions-json"],heading:[1],background:[1],basePath:[1,"base-path"],currentUrl:[1,"current-url"],resolvedTabs:[32],resolvedActions:[32],urlDerivedValue:[32],hideTabsForDetailRoute:[32],tabsCollapsed:[32],menuOpen:[32],tabLayoutCommitted:[32],triggerLabelTruncated:[32]},undefined,{tabs:[{onPropsChange:0}],tabsJson:[{onPropsChange:0}],actions:[{onPropsChange:0}],actionsJson:[{onPropsChange:0}],currentUrl:[{onUrlChange:0}],basePath:[{onUrlChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}]);w.HOST_PROP_SYNC_BUDGET=8;w.INTRINSIC_WIDTH_RETRY_MAX=3;function x(){if(typeof customElements==="undefined"){return}const e=["ds-bar-nav","ds-bar-nav-action","ds-icon","ds-menu","ds-tab-group-nav"];e.forEach((e=>{switch(e){case"ds-bar-nav":if(!customElements.get(n(e))){customElements.define(n(e),w)}break;case"ds-bar-nav-action":if(!customElements.get(n(e))){h()}break;case"ds-icon":if(!customElements.get(n(e))){d()}break;case"ds-menu":if(!customElements.get(n(e))){c()}break;case"ds-tab-group-nav":if(!customElements.get(n(e))){b()}break}}))}x();const C=w;const z=x;export{C as DsBarNav,z as defineCustomElement};
|
|
1
|
+
import{p as e,H as t,c as a,h as s,a as i,t as n}from"./index.js";import{g as r,i as o}from"./p-BQq26pt9.js";import{d as h}from"./p-B_enucPQ.js";import{d}from"./p-qfvbc9w-.js";import{d as c}from"./p-DrDrPeVV.js";import{d as b}from"./p-CpbnmEu1.js";import{d as l}from"./p-DOtcc9UU.js";function u(e,t,a){if(!e||!t){return{value:"",hideTabs:false}}if(e!==t&&!e.startsWith(`${t}/`)){return{value:"",hideTabs:false}}const s=e.slice(t.length);const i=s.startsWith("/")?s.slice(1).split("/")[0]:"";const n=r(a);if(!i){return{value:n[0]?.id??"",hideTabs:false}}const o=n.find((e=>e.id===i));if(o){return{value:o.id,hideTabs:false}}return{value:"",hideTabs:true}}function v(e,t,a,s,i,n){const r=a?f(a,[]):t??[];const o=n?f(n,[]):i??[];return e.length===0&&r.length>0||s.length===0&&o.length>0}function f(e,t){if(Array.isArray(e))return e;if(typeof e==="string"&&e!==""){try{const a=JSON.parse(e);return Array.isArray(a)?a:t}catch{return t}}return t}function g(e,t){if(!e)return null;const a=e.shadowRoot??e;return a.querySelector(t)}function p(e){return g(e,'[role="tablist"]')}function m(e,t){const a=[];let s=[];for(const i of e){if(o(i)){if(s.length>0){a.push({items:s});s=[]}continue}s.push({label:i.label,value:i.id,isSelected:i.id===t,isInactive:i.disabled})}if(s.length>0){a.push({items:s})}return a}function _(e,t){const a=r(e);return a.find((e=>e.id===t))??a[0]}function k(e,t){return _(e,t)?.label??"Tabs"}function y(e,t,a,s=2){const i=e-t;if(a){return i>-s}return i>s}const w=()=>`.sc-ds-bar-nav-h{display:block}.bar-nav.sc-ds-bar-nav{display:flex;align-items:center;position:relative;height:var(--dimension-size-600);padding:var(--dimension-space-100);gap:var(--dimension-space-100);box-sizing:border-box;border-bottom:var(--dimension-stroke-width-012) solid var(--color-border-tertiary)}.bg-primary.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-primary);background-color:var(--_bar-nav-bg)}.bg-secondary.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-secondary);background-color:var(--_bar-nav-bg)}.bg-transparent.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-primary);background-color:transparent}.bg-translucent.sc-ds-bar-nav{--_bar-nav-bg:var(--color-background-translucent);background-color:var(--_bar-nav-bg);backdrop-filter:blur(var(--effect-blur-md));-webkit-backdrop-filter:blur(var(--effect-blur-md))}.bar-nav--tabs-collapsed.sc-ds-bar-nav{display:flex;gap:0;align-items:center}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger.sc-ds-bar-nav{flex:0 1 auto;min-width:0;max-width:100%;width:auto;overflow:hidden}.bar-nav__between.sc-ds-bar-nav{flex:1 1 0%;min-width:var(--dimension-space-100)}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label.sc-ds-bar-nav{flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:block;flex:1 1 0%;min-width:0}.bar-nav--tabs-collapsed.sc-ds-bar-nav .bar-nav__actions.sc-ds-bar-nav{flex:0 0 auto;margin-left:0}.bar-nav__left.sc-ds-bar-nav{position:relative;flex:1 1 0%;min-width:0;width:0;display:flex;align-items:center}.bar-nav__left.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{flex:1;min-width:0}.bar-nav__tabs-probe.sc-ds-bar-nav{position:absolute;left:0;top:0;visibility:hidden;pointer-events:none;overflow:visible;width:max-content;max-width:none;z-index:-1}.bar-nav__tabs-probe.sc-ds-bar-nav ds-tab-group-nav.sc-ds-bar-nav{width:max-content}.bar-nav__tabs-visible.sc-ds-bar-nav{width:100%;min-width:0}.bar-nav__tabs-pending.sc-ds-bar-nav{flex:1;min-width:0;height:var(--dimension-size-400);visibility:hidden;pointer-events:none}.bar-nav__tab-trigger.sc-ds-bar-nav{all:unset;box-sizing:border-box;display:inline-flex;align-items:center;gap:var(--dimension-space-050);flex:0 1 auto;min-width:0;width:max-content;max-width:100%;padding:var(--dimension-space-075);background-color:transparent;border-radius:var(--dimension-radius-025);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--color-foreground-primary);position:relative;transition:color var(--effect-motion-short-2);height:var(--dimension-size-400);--_hover-bg:var(--color-interaction-hover);--_pressed-bg:var(--color-interaction-pressed);--_dot:var(--color-foreground-bold-brand);--_dot-ring:var(--color-background-secondary)}.bar-nav__tab-trigger.sc-ds-bar-nav::after{content:'';position:absolute;inset:0;border-radius:var(--dimension-radius-025);background:transparent;pointer-events:none;transition:none;z-index:2}.bar-nav__tab-trigger.sc-ds-bar-nav:hover::after{background:var(--_hover-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:active::after{background:var(--_pressed-bg);transition:none}.bar-nav__tab-trigger.sc-ds-bar-nav:focus-visible{outline:var(--dimension-stroke-width-025) solid var(--color-interaction-focus);outline-offset:var(--dimension-space-025)}.bar-nav__tab-trigger--open.sc-ds-bar-nav::after{background:var(--_hover-bg)}.bar-nav__tab-trigger-label.sc-ds-bar-nav{position:relative;display:inline-flex;align-items:center;flex:0 1 auto;min-width:0;max-width:100%;padding:0 var(--dimension-space-025);overflow:hidden;--_fade-right:var(--dimension-space-025);z-index:1}.bar-nav__tab-trigger-label--truncated.sc-ds-bar-nav::after{content:'';position:absolute;top:0;right:var(--_fade-right);bottom:0;width:var(--dimension-size-400);background:linear-gradient(to right, transparent, var(--_bar-nav-bg));pointer-events:none;z-index:1}.bar-nav__tab-trigger-label-text.sc-ds-bar-nav{display:inline-block;max-width:100%;box-sizing:border-box;white-space:nowrap;overflow:hidden;vertical-align:bottom}.bar-nav__tab-trigger-label-text--truncated.sc-ds-bar-nav{-webkit-mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );mask-image:linear-gradient( to right, #000 0, #000 calc(100% - var(--dimension-size-400)), transparent 100% );-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%}.bar-nav__tab-trigger-label--dot.sc-ds-bar-nav{padding-right:calc(var(--dimension-space-025) + var(--dimension-space-050));--_fade-right:calc(var(--dimension-space-025) + var(--dimension-space-050))}.bar-nav__tab-trigger-dot.sc-ds-bar-nav{position:absolute;top:0;right:0;pointer-events:none;z-index:1}.bar-nav__tab-trigger-chevron.sc-ds-bar-nav{position:relative;flex-shrink:0;z-index:1}.bar-nav__heading.sc-ds-bar-nav{display:inline-flex;align-items:center;height:var(--dimension-size-400);padding-inline:var(--dimension-space-100);color:var(--color-foreground-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bar-nav__actions.sc-ds-bar-nav{display:flex;align-items:center;gap:var(--dimension-space-050);flex:0 0 auto;margin-left:auto}`;const x=e(class e extends t{constructor(e){super();if(e!==false){this.__registerHost()}this.dsTabChange=a(this,"dsTabChange");this.dsActionChange=a(this,"dsActionChange");this.tabs=[];this.tabsJson="";this.value="";this.actions=[];this.actionsJson="";this.background="secondary";this.basePath="";this.currentUrl="";this.resolvedTabs=[];this.resolvedActions=[];this.urlDerivedValue="";this.hideTabsForDetailRoute=false;this.tabsCollapsed=false;this.menuOpen=false;this.tabLayoutCommitted=false;this.triggerLabelTruncated=false;this.headerEl=null;this.triggerEl=null;this.triggerLabelTextEl=null;this.triggerLabelObserver=null;this.menuEl=null;this.visibleTabGroupEl=null;this.probeTabGroupEl=null;this.resizeObserver=null;this.overflowCheckScheduled=false;this.intrinsicWidthRetryCount=0}get effectiveValue(){if(this.currentUrl&&this.basePath){return this.urlDerivedValue}return this.value}get activeTabLabel(){return k(this.resolvedTabs,this.effectiveValue)}get activeTabHasDot(){return!!_(this.resolvedTabs,this.effectiveValue)?.dot}onPropsChange(){this.resolvedTabs=this.tabsJson?f(this.tabsJson,[]):this.tabs??[];this.resolvedActions=this.actionsJson?f(this.actionsJson,[]):this.actions??[];this.syncValueFromUrl();this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}onUrlChange(){this.syncValueFromUrl();this.scheduleOverflowCheck()}onSelectionChange(){this.syncMenuSections();this.scheduleOverflowCheck()}onMenuOpenChange(e){if(this.menuEl){this.menuEl.open=e}}onTabsCollapsedChange(e,t){if(!e){this.menuOpen=false;this.menuEl=null;this.triggerLabelTruncated=false;this.syncTriggerLabelObserver()}this.scheduleOverflowCheck();if(e){requestAnimationFrame((()=>{this.scheduleOverflowCheck();this.syncTriggerLabelObserver()}))}if(e||t===undefined||t===e)return;requestAnimationFrame((()=>this.scheduleOverflowCheck()));queueMicrotask((()=>this.focusVisibleSelectedTab()))}componentWillLoad(){this.onPropsChange()}componentDidLoad(){this.syncHostPropsIfNeeded();this.scheduleDeferredHostPropSync();this.setupOverflowObserver();this.scheduleOverflowCheck()}componentDidRender(){this.scheduleOverflowCheck();this.syncMenuAnchor();if(this.tabsCollapsed){this.updateTriggerLabelTruncation()}}disconnectedCallback(){this.resizeObserver?.disconnect();this.resizeObserver=null;this.syncTriggerLabelObserver(true)}syncHostPropsIfNeeded(){if(v(this.resolvedTabs,this.tabs,this.tabsJson,this.resolvedActions,this.actions,this.actionsJson)){this.onPropsChange()}else if(this.currentUrl&&this.basePath){this.syncValueFromUrl()}}scheduleDeferredHostPropSync(){let t=e.HOST_PROP_SYNC_BUDGET;const a=()=>{this.syncHostPropsIfNeeded();if(--t>0){requestAnimationFrame(a)}};queueMicrotask(a)}setupOverflowObserver(){if(typeof ResizeObserver==="undefined"||!this.headerEl)return;this.resizeObserver?.disconnect();this.resizeObserver=new ResizeObserver((()=>this.scheduleOverflowCheck()));this.resizeObserver.observe(this.headerEl)}scheduleOverflowCheck(){if(this.overflowCheckScheduled)return;this.overflowCheckScheduled=true;requestAnimationFrame((()=>{this.overflowCheckScheduled=false;this.updateTabsCollapsed();this.updateTriggerLabelTruncation()}))}syncTriggerLabelObserver(e=false){this.triggerLabelObserver?.disconnect();this.triggerLabelObserver=null;if(e||!this.tabsCollapsed||!this.triggerLabelTextEl){return}this.updateTriggerLabelTruncation();if(typeof ResizeObserver==="undefined")return;this.triggerLabelObserver=new ResizeObserver((()=>this.updateTriggerLabelTruncation()));this.triggerLabelObserver.observe(this.triggerLabelTextEl);if(this.triggerEl){this.triggerLabelObserver.observe(this.triggerEl)}}updateTriggerLabelTruncation(){const e=this.triggerLabelTextEl;if(!e||!this.tabsCollapsed){if(this.triggerLabelTruncated){this.triggerLabelTruncated=false}return}const t=e.scrollWidth>e.clientWidth+1;if(t!==this.triggerLabelTruncated){this.triggerLabelTruncated=t}}getLeftZoneAvailableWidth(){if(!this.headerEl)return 0;const e=getComputedStyle(this.headerEl);const t=parseFloat(e.columnGap||e.gap||"0")||0;const a=this.headerEl.querySelector(".bar-nav__actions");const s=a?.offsetWidth??0;const i=(parseFloat(e.paddingLeft)||0)+(parseFloat(e.paddingRight)||0);const n=this.tabsCollapsed?parseFloat(getComputedStyle(this.headerEl).getPropertyValue("--dimension-space-100").trim())||8:a?t:0;const r=this.headerEl.clientWidth-i-s-n;return Math.max(0,r)}getTabsIntrinsicWidth(){const e=p(this.probeTabGroupEl);return e?.scrollWidth??0}scheduleIntrinsicWidthRetry(){if(this.intrinsicWidthRetryCount>=e.INTRINSIC_WIDTH_RETRY_MAX)return;this.intrinsicWidthRetryCount++;requestAnimationFrame((()=>this.scheduleOverflowCheck()))}updateTabsCollapsed(){if(!this.headerEl||this.resolvedTabs.length===0||this.hideTabsForDetailRoute){if(this.tabsCollapsed){this.tabsCollapsed=false;this.menuOpen=false}this.intrinsicWidthRetryCount=0;return}const e=this.getTabsIntrinsicWidth();if(e===0){this.scheduleIntrinsicWidthRetry();return}this.intrinsicWidthRetryCount=0;const t=y(e,this.getLeftZoneAvailableWidth(),this.tabsCollapsed);if(t!==this.tabsCollapsed){this.tabsCollapsed=t;if(!t){this.menuOpen=false}}}syncMenuAnchor(){if(!this.menuEl||!this.triggerEl||!this.tabsCollapsed)return;this.menuEl.anchor=this.triggerEl;this.syncMenuSections()}handleMenuSelect(e){const t=e.detail;if(t?.value!==undefined){this.selectTab(String(t.value))}this.menuOpen=false}handleMenuClose(){this.menuOpen=false}syncMenuSections(){if(!this.menuEl)return;this.menuEl.sections=m(this.resolvedTabs,this.effectiveValue)}syncValueFromUrl(){if(!this.currentUrl||!this.basePath){this.urlDerivedValue="";this.hideTabsForDetailRoute=false;return}const{value:e,hideTabs:t}=u(this.currentUrl,this.basePath,this.resolvedTabs);this.urlDerivedValue=e;this.hideTabsForDetailRoute=t}selectTab(e){this.value=e;this.dsTabChange.emit(e)}focusVisibleSelectedTab(){const e=g(this.visibleTabGroupEl,`[data-tab-id="${this.effectiveValue}"]`);e?.focus({preventScroll:true})}handleTabChange(e){this.selectTab(e.detail)}handleActionChange(e,t){const a=t.detail;this.dsActionChange.emit({id:e,selected:a})}toggleTabMenu(){if(this.menuOpen){this.menuOpen=false;return}if(this.menuEl&&this.triggerEl){this.menuEl.anchor=this.triggerEl;this.menuEl.minWidth=`${this.triggerEl.offsetWidth}px`;this.syncMenuSections()}this.menuOpen=true}handleTriggerKeyDown(e){if(!this.tabsCollapsed)return;if(!this.menuOpen){if(e.key==="ArrowDown"||e.key==="ArrowUp"||e.key==="Enter"||e.key===" "){e.preventDefault();this.toggleTabMenu()}return}if(e.key==="Escape"){e.preventDefault();this.menuOpen=false;this.triggerEl?.focus()}}render(){const e=this.resolvedTabs.length>0&&!this.hideTabsForDetailRoute;const t={};const a=t[this.background];return s(i,{key:"6a9d06038e714910ee3375976014d5afe659e2c6"},s("header",{key:"3c4d7c65013ce9da9c4a1d9588446bfdbdf1bcb4",class:{"bar-nav":true,[`bg-${this.background}`]:true,"bar-nav--tabs-collapsed":e&&this.tabsCollapsed},ref:e=>{this.headerEl=e;if(e&&!this.resizeObserver){this.setupOverflowObserver()}}},e&&s("div",{key:"36f1e91251e9989b80a3bb281f2847158759cb4d",class:"bar-nav__tabs-probe","aria-hidden":"true",inert:true},s("ds-tab-group-nav",{key:"a24197e86bdde94923267d19c423886dfd363de3",ref:e=>{this.probeTabGroupEl=e??null;if(e){this.intrinsicWidthRetryCount=0;this.scheduleOverflowCheck()}},tabs:this.resolvedTabs,value:this.effectiveValue})),e&&!this.tabsCollapsed&&s("div",{key:"7bc48ddd515153663513ab7c16609fa94183816f",class:"bar-nav__left"},s("ds-tab-group-nav",{key:"f80f1d9cc146da03f90585e4649d2705fe2c705b",class:"bar-nav__tabs-visible",ref:e=>{this.visibleTabGroupEl=e??null},tabs:this.resolvedTabs,value:this.effectiveValue,onDsChange:e=>this.handleTabChange(e)})),!e&&this.heading&&s("span",{key:"19019151704839426b23973cbc5699bdc6b270ca",class:"bar-nav__heading text-body-medium-emphasis"},this.heading),e&&this.tabsCollapsed&&s("button",{key:"9aaafe90f6ac0978dc1f25515f7ee3cd7f6ad19d",type:"button",class:{"bar-nav__tab-trigger":true,"bar-nav__tab-trigger--open":this.menuOpen},ref:e=>{this.triggerEl=e},"aria-haspopup":"menu","aria-expanded":this.menuOpen,"aria-label":`${this.activeTabLabel} tabs`,onClick:()=>this.toggleTabMenu(),onKeyDown:e=>this.handleTriggerKeyDown(e)},s("span",{key:"0eaac771fba9716c6be8de618927129d74c2c92c",class:{"bar-nav__tab-trigger-label":true,"bar-nav__tab-trigger-label--dot":this.activeTabHasDot,"bar-nav__tab-trigger-label--truncated":this.triggerLabelTruncated}},s("span",{key:"79eada547183c260649ced329217039ed76c154c",class:{"bar-nav__tab-trigger-label-text":true,"bar-nav__tab-trigger-label-text--truncated":this.triggerLabelTruncated,"text-body-medium-emphasis":true},ref:e=>{const t=e??null;if(t===this.triggerLabelTextEl)return;this.triggerLabelTextEl=t;if(this.tabsCollapsed){this.syncTriggerLabelObserver()}}},this.activeTabLabel),this.activeTabHasDot&&s("ds-badge",{key:"d01174ec2e7472c420057eb7c1bcf5caeb59e78c",class:"bar-nav__tab-trigger-dot",variant:"dot",background:"var(--_dot-ring)",label:"","aria-hidden":"true"})),s("ds-icon",{key:"0ad57d2982bf042c1182635d450f4535ac3a9e8c",name:"ChevronDown",size:"md",color:"inherit",class:"bar-nav__tab-trigger-chevron"})),e&&this.tabsCollapsed&&this.resolvedActions.length>0&&s("div",{key:"3810a859c0478ec91eb4afdeb3e8659964e1f9fa",class:"bar-nav__between","aria-hidden":"true"}),this.resolvedActions.length>0&&s("div",{key:"96f178d000fc3bb3d9581f416931640f55035c6b",class:"bar-nav__actions"},this.resolvedActions.map((e=>s("ds-bar-nav-action",{key:e.id,icon:e.icon,selected:e.selected??false,dot:e.dot??false,inactive:e.inactive,"aria-label":e.ariaLabel??e.id,background:a,onDsChange:t=>this.handleActionChange(e.id,t)}))))),e&&this.tabsCollapsed&&s("ds-menu",{key:"4e1522090ab98325cbc554874a50d32d34400472",ref:e=>{this.menuEl=e??null},open:this.menuOpen,sections:m(this.resolvedTabs,this.effectiveValue),side:"bottom",align:"start",onDsSelect:e=>this.handleMenuSelect(e),onDsClose:()=>this.handleMenuClose()}))}static get watchers(){return{tabs:[{onPropsChange:0}],tabsJson:[{onPropsChange:0}],actions:[{onPropsChange:0}],actionsJson:[{onPropsChange:0}],currentUrl:[{onUrlChange:0}],basePath:[{onUrlChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}}static get style(){return w()}},[2,"ds-bar-nav",{tabs:[16],tabsJson:[1,"tabs-json"],value:[1025],actions:[16],actionsJson:[1,"actions-json"],heading:[1],background:[1],basePath:[1,"base-path"],currentUrl:[1,"current-url"],resolvedTabs:[32],resolvedActions:[32],urlDerivedValue:[32],hideTabsForDetailRoute:[32],tabsCollapsed:[32],menuOpen:[32],tabLayoutCommitted:[32],triggerLabelTruncated:[32]},undefined,{tabs:[{onPropsChange:0}],tabsJson:[{onPropsChange:0}],actions:[{onPropsChange:0}],actionsJson:[{onPropsChange:0}],currentUrl:[{onUrlChange:0}],basePath:[{onUrlChange:0}],value:[{onSelectionChange:0}],urlDerivedValue:[{onSelectionChange:0}],menuOpen:[{onMenuOpenChange:0}],tabsCollapsed:[{onTabsCollapsedChange:0}]}]);x.HOST_PROP_SYNC_BUDGET=8;x.INTRINSIC_WIDTH_RETRY_MAX=3;function C(){if(typeof customElements==="undefined"){return}const e=["ds-bar-nav","ds-badge","ds-bar-nav-action","ds-icon","ds-menu","ds-tab-group-nav"];e.forEach((e=>{switch(e){case"ds-bar-nav":if(!customElements.get(n(e))){customElements.define(n(e),x)}break;case"ds-badge":if(!customElements.get(n(e))){h()}break;case"ds-bar-nav-action":if(!customElements.get(n(e))){d()}break;case"ds-icon":if(!customElements.get(n(e))){c()}break;case"ds-menu":if(!customElements.get(n(e))){b()}break;case"ds-tab-group-nav":if(!customElements.get(n(e))){l()}break}}))}C();const T=x;const z=C;export{T as DsBarNav,z as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-bar-nav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["deriveBarNavValueFromUrl","path","basePath","tabs","value","hideTabs","startsWith","remainder","slice","length","seg","split","selectableTabs","getSelectableTabs","id","tab","find","t","shouldResyncBarNavProps","resolvedTabs","tabsJson","resolvedActions","actions","actionsJson","tabsIncoming","parseJsonArrayProp","actionsIncoming","fallback","Array","isArray","parsed","JSON","parse","queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","selectedId","sections","batch","item","isTabDivider","push","items","label","isSelected","isInactive","disabled","getActiveTab","selectable","getActiveTabLabel","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","background","currentUrl","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","triggerLabelTruncated","headerEl","triggerEl","triggerLabelTextEl","triggerLabelObserver","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","overflowCheckScheduled","intrinsicWidthRetryCount","effectiveValue","activeTabLabel","activeTabHasDot","dot","onPropsChange","syncValueFromUrl","scheduleOverflowCheck","onUrlChange","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","syncTriggerLabelObserver","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","componentDidRender","syncMenuAnchor","updateTriggerLabelTruncation","disconnectedCallback","disconnect","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","updateTabsCollapsed","disconnectOnly","el","truncated","scrollWidth","clientWidth","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","gap","parseFloat","columnGap","actionsEl","actionsWidth","offsetWidth","horizontalPadding","paddingLeft","paddingRight","spacing","getPropertyValue","trim","available","Math","max","getTabsIntrinsicWidth","tabList","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","intrinsicWidth","shouldCollapse","anchor","handleMenuSelect","e","detail","selectTab","String","handleMenuClose","dsTabChange","emit","focus","preventScroll","handleTabChange","handleActionChange","actionId","selected","dsActionChange","toggleTabMenu","minWidth","handleTriggerKeyDown","key","preventDefault","render","hasTabs","bgToActionBg","actionBg","h","Host","class","ref","inert","onDsChange","heading","type","onClick","onKeyDown","next","name","size","color","map","action","icon","inactive","ariaLabel","side","align","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-utils.ts","src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["import { getSelectableTabs } from '../TabGroup/tab-item-utils';\nimport type { BarNavActionItem, BarNavTab } from './BarNav';\n\nexport interface BarNavUrlState {\n /** Tab id derived from the URL, or empty when none applies. */\n value: string;\n /** When true, tabs should be hidden (e.g. non-tab child routes like detail pages). */\n hideTabs: boolean;\n}\n\n/** Derive BarNav tab selection from `currentUrl` relative to `basePath`.\n * Mirrors motive-webapp-lab `resolveBarNavState` tab-selection semantics. */\nexport function deriveBarNavValueFromUrl(\n path: string,\n basePath: string,\n tabs: BarNavTab[],\n): BarNavUrlState {\n if (!path || !basePath) {\n return { value: '', hideTabs: false };\n }\n\n if (path !== basePath && !path.startsWith(`${basePath}/`)) {\n return { value: '', hideTabs: false };\n }\n\n const remainder = path.slice(basePath.length);\n const seg = remainder.startsWith('/') ? remainder.slice(1).split('/')[0] : '';\n const selectableTabs = getSelectableTabs(tabs);\n\n if (!seg) {\n return { value: selectableTabs[0]?.id ?? '', hideTabs: false };\n }\n\n const tab = selectableTabs.find(t => t.id === seg);\n if (tab) {\n return { value: tab.id, hideTabs: false };\n }\n\n return { value: '', hideTabs: true };\n}\n\n/** True when host array/json props have data but resolved internal state is still empty. */\nexport function shouldResyncBarNavProps(\n resolvedTabs: BarNavTab[],\n tabs: BarNavTab[],\n tabsJson: string,\n resolvedActions: BarNavActionItem[],\n actions: BarNavActionItem[],\n actionsJson: string,\n): boolean {\n const tabsIncoming = tabsJson\n ? parseJsonArrayProp(tabsJson, [])\n : (tabs ?? []);\n const actionsIncoming = actionsJson\n ? parseJsonArrayProp(actionsJson, [])\n : (actions ?? []);\n\n return (\n (resolvedTabs.length === 0 && tabsIncoming.length > 0) ||\n (resolvedActions.length === 0 && actionsIncoming.length > 0)\n );\n}\n\n/** Parse tabs/actions from either a JSON attribute string or a JS property array. */\nexport function parseJsonArrayProp<T>(value: string | T[] | undefined, fallback: T[]): T[] {\n if (Array.isArray(value)) return value;\n if (typeof value === 'string' && value !== '') {\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : fallback;\n } catch {\n return fallback;\n }\n }\n return fallback;\n}\n","export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuSection } from '../Menu/Menu';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuSection['items'] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n",":host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--color-border-tertiary);\n}\n\n/* Background variants — mirrors ds-header pattern */\n.bg-primary {\n --_bar-nav-bg: var(--color-background-primary);\n background-color: var(--_bar-nav-bg);\n}\n.bg-secondary {\n --_bar-nav-bg: var(--color-background-secondary);\n background-color: var(--_bar-nav-bg);\n}\n.bg-transparent {\n --_bar-nav-bg: var(--color-background-primary);\n background-color: transparent;\n}\n.bg-translucent {\n --_bar-nav-bg: var(--color-background-translucent);\n background-color: var(--_bar-nav-bg);\n backdrop-filter: blur(var(--effect-blur-md));\n -webkit-backdrop-filter: blur(var(--effect-blur-md));\n}\n\n/* Collapsed — explicit spacer keeps the 8px minimum while the trigger can shrink. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: 0;\n align-items: center;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n width: auto;\n overflow: hidden;\n}\n\n.bar-nav__between {\n flex: 1 1 0%;\n min-width: var(--dimension-space-100);\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label {\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label-text {\n display: block;\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__actions {\n flex: 0 0 auto;\n margin-left: 0;\n}\n\n/* Expanded tabs — consume space between start and actions */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Collapsed tab trigger — mirrors TabGroup .tab (+ chevron when collapsed) */\n.bar-nav__tab-trigger {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 1 auto;\n min-width: 0;\n width: max-content;\n max-width: 100%;\n padding: var(--dimension-space-075);\n background-color: transparent;\n border-radius: var(--dimension-radius-025);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--color-foreground-primary);\n position: relative;\n transition: color var(--effect-motion-short-2);\n height: var(--dimension-size-400);\n --_hover-bg: var(--color-interaction-hover);\n --_pressed-bg: var(--color-interaction-pressed);\n --_dot: var(--color-foreground-bold-brand);\n --_dot-ring: var(--color-background-secondary);\n}\n\n.bar-nav__tab-trigger::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n transition: none;\n z-index: 2;\n}\n\n.bar-nav__tab-trigger:hover::after {\n background: var(--_hover-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:active::after {\n background: var(--_pressed-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.bar-nav__tab-trigger--open::after {\n background: var(--_hover-bg);\n}\n\n.bar-nav__tab-trigger-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n padding: 0 var(--dimension-space-025);\n overflow: hidden;\n --_fade-right: var(--dimension-space-025);\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label--truncated::after {\n content: '';\n position: absolute;\n top: 0;\n right: var(--_fade-right);\n bottom: 0;\n width: var(--dimension-size-400);\n background: linear-gradient(to right, transparent, var(--_bar-nav-bg));\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label-text {\n display: inline-block;\n max-width: 100%;\n box-sizing: border-box;\n white-space: nowrap;\n overflow: hidden;\n vertical-align: bottom;\n}\n\n.bar-nav__tab-trigger-label-text--truncated {\n -webkit-mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-size: 100% 100%;\n mask-size: 100% 100%;\n}\n\n.bar-nav__tab-trigger-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n --_fade-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-trigger-dot {\n position: absolute;\n top: 0;\n right: 0;\n width: var(--dimension-size-075, calc(var(--dimension-size-base) * 3 / 4));\n height: var(--dimension-size-075, calc(var(--dimension-size-base) * 3 / 4));\n border-radius: var(--dimension-radius-half);\n background: var(--_dot);\n box-shadow: 0 0 0 var(--dimension-stroke-width-018) var(--_dot-ring);\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-chevron {\n position: relative;\n flex-shrink: 0;\n z-index: 1;\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--color-foreground-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Right zone — pinned to the end; header gap is the min space from tabs/trigger */\n.bar-nav__actions {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 0 auto;\n margin-left: auto;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { MenuItemData } from '../Menu/Menu';\nimport type { BarNavActionBackground } from '../BarNavAction/BarNavAction';\nimport type { TabItem } from '../TabGroup/tab-item-utils';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n getActiveTab,\n getActiveTabLabel,\n tabsOverflowContainer,\n tabsToMenuSections,\n} from './bar-nav-tabs-menu-utils';\n\nexport type BarNavBackground = 'primary' | 'secondary' | 'transparent' | 'translucent';\n\n/** Same shape as `TabItem` — supports `{ type: 'divider' }` between tab groups. */\nexport type BarNavTab = TabItem;\n\nexport interface BarNavActionItem {\n id: string;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Whether this action button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n inactive?: boolean;\n ariaLabel?: string;\n}\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Action items rendered in the right section.\n * Set via JS property: `el.actions = [...]`. Replace the array reference to update.\n */\n @Prop() actions: BarNavActionItem[] = [];\n\n /** JSON fallback for `actions` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'actions-json' }) actionsJson: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Surface background variant. */\n @Prop() background: BarNavBackground = 'secondary';\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n /** Emitted when an action button is toggled. Detail = { id, selected }. */\n @Event() dsActionChange!: EventEmitter<{ id: string; selected: boolean }>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private resolvedActions: BarNavActionItem[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private triggerLabelTruncated = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: HTMLButtonElement | null = null;\n private triggerLabelTextEl: HTMLElement | null = null;\n private triggerLabelObserver: ResizeObserver | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: QueryableHost | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private overflowCheckScheduled = false;\n private intrinsicWidthRetryCount = 0;\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get activeTabLabel(): string {\n return getActiveTabLabel(this.resolvedTabs, this.effectiveValue);\n }\n\n private get activeTabHasDot(): boolean {\n return !!getActiveTab(this.resolvedTabs, this.effectiveValue)?.dot;\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('actions')\n @Watch('actionsJson')\n onPropsChange() {\n this.resolvedTabs = this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n this.resolvedActions = this.actionsJson\n ? parseJsonArrayProp(this.actionsJson, [])\n : (this.actions ?? []);\n this.syncValueFromUrl();\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n\n @Watch('currentUrl')\n @Watch('basePath')\n onUrlChange() {\n this.syncValueFromUrl();\n this.scheduleOverflowCheck();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuEl = null;\n this.triggerLabelTruncated = false;\n this.syncTriggerLabelObserver();\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n this.syncTriggerLabelObserver();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.onPropsChange();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n if (this.tabsCollapsed) {\n this.updateTriggerLabelTruncation();\n }\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.syncTriggerLabelObserver(true);\n }\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (\n shouldResyncBarNavProps(\n this.resolvedTabs,\n this.tabs,\n this.tabsJson,\n this.resolvedActions,\n this.actions,\n this.actionsJson,\n )\n ) {\n this.onPropsChange();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => this.scheduleOverflowCheck());\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.overflowCheckScheduled) return;\n this.overflowCheckScheduled = true;\n requestAnimationFrame(() => {\n this.overflowCheckScheduled = false;\n this.updateTabsCollapsed();\n this.updateTriggerLabelTruncation();\n });\n }\n\n private syncTriggerLabelObserver(disconnectOnly = false) {\n this.triggerLabelObserver?.disconnect();\n this.triggerLabelObserver = null;\n\n if (disconnectOnly || !this.tabsCollapsed || !this.triggerLabelTextEl) {\n return;\n }\n\n this.updateTriggerLabelTruncation();\n\n if (typeof ResizeObserver === 'undefined') return;\n\n this.triggerLabelObserver = new ResizeObserver(() => this.updateTriggerLabelTruncation());\n this.triggerLabelObserver.observe(this.triggerLabelTextEl);\n if (this.triggerEl) {\n this.triggerLabelObserver.observe(this.triggerEl);\n }\n }\n\n private updateTriggerLabelTruncation() {\n const el = this.triggerLabelTextEl;\n if (!el || !this.tabsCollapsed) {\n if (this.triggerLabelTruncated) {\n this.triggerLabelTruncated = false;\n }\n return;\n }\n\n const truncated = el.scrollWidth > el.clientWidth + 1;\n if (truncated !== this.triggerLabelTruncated) {\n this.triggerLabelTruncated = truncated;\n }\n }\n\n /** Width left for tabs after actions. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const gap = parseFloat(headerStyle.columnGap || headerStyle.gap || '0') || 0;\n const actionsEl = this.headerEl.querySelector('.bar-nav__actions') as HTMLElement | null;\n const actionsWidth = actionsEl?.offsetWidth ?? 0;\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n const spacing = this.tabsCollapsed\n ? parseFloat(\n getComputedStyle(this.headerEl).getPropertyValue('--dimension-space-100').trim(),\n ) || 8\n : actionsEl\n ? gap\n : 0;\n const available =\n this.headerEl.clientWidth - horizontalPadding - actionsWidth - spacing;\n\n return Math.max(0, available);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.tabsCollapsed = false;\n this.menuOpen = false;\n }\n this.intrinsicWidthRetryCount = 0;\n return;\n }\n\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (intrinsicWidth === 0) {\n this.scheduleIntrinsicWidthRetry();\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n );\n\n if (shouldCollapse !== this.tabsCollapsed) {\n this.tabsCollapsed = shouldCollapse;\n if (!shouldCollapse) {\n this.menuOpen = false;\n }\n }\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.tabsCollapsed) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToMenuSections(this.resolvedTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n this.resolvedTabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private handleActionChange(actionId: string, e: Event) {\n const selected = (e as CustomEvent<boolean>).detail;\n this.dsActionChange.emit({ id: actionId, selected });\n }\n\n private toggleTabMenu() {\n if (this.menuOpen) {\n this.menuOpen = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = `${this.triggerEl.offsetWidth}px`;\n this.syncMenuSections();\n }\n\n this.menuOpen = true;\n }\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.tabsCollapsed) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu();\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.triggerEl?.focus();\n }\n }\n\n render() {\n const hasTabs = this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n\n const bgToActionBg: Partial<Record<BarNavBackground, BarNavActionBackground>> = {};\n const actionBg: BarNavActionBackground | undefined = bgToActionBg[this.background];\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n [`bg-${this.background}`]: true,\n 'bar-nav--tabs-collapsed': hasTabs && this.tabsCollapsed,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n ref={el => {\n this.probeTabGroupEl = el ?? null;\n if (el) {\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && !this.tabsCollapsed && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n />\n </div>\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.tabsCollapsed && (\n <button\n type=\"button\"\n class={{\n 'bar-nav__tab-trigger': true,\n 'bar-nav__tab-trigger--open': this.menuOpen,\n }}\n ref={el => {\n this.triggerEl = el as HTMLButtonElement;\n }}\n aria-haspopup=\"menu\"\n aria-expanded={this.menuOpen}\n aria-label={`${this.activeTabLabel} tabs`}\n onClick={() => this.toggleTabMenu()}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label': true,\n 'bar-nav__tab-trigger-label--dot': this.activeTabHasDot,\n 'bar-nav__tab-trigger-label--truncated': this.triggerLabelTruncated,\n }}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label-text': true,\n 'bar-nav__tab-trigger-label-text--truncated': this.triggerLabelTruncated,\n 'text-body-medium-emphasis': true,\n }}\n ref={el => {\n const next = el ?? null;\n if (next === this.triggerLabelTextEl) return;\n this.triggerLabelTextEl = next;\n if (this.tabsCollapsed) {\n this.syncTriggerLabelObserver();\n }\n }}\n >\n {this.activeTabLabel}\n </span>\n {this.activeTabHasDot && (\n <span class=\"bar-nav__tab-trigger-dot\" aria-hidden=\"true\" />\n )}\n </span>\n <ds-icon\n name=\"ChevronDown\"\n size=\"md\"\n color=\"inherit\"\n class=\"bar-nav__tab-trigger-chevron\"\n />\n </button>\n )}\n\n {hasTabs && this.tabsCollapsed && this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__between\" aria-hidden=\"true\" />\n )}\n\n {this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__actions\">\n {this.resolvedActions.map(action => (\n <ds-bar-nav-action\n key={action.id}\n icon={action.icon}\n selected={action.selected ?? false}\n dot={action.dot ?? false}\n inactive={action.inactive}\n aria-label={action.ariaLabel ?? action.id}\n background={actionBg}\n onDsChange={(e: Event) => this.handleActionChange(action.id, e)}\n />\n ))}\n </div>\n )}\n\n </header>\n\n {hasTabs && this.tabsCollapsed && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToMenuSections(this.resolvedTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"start\"\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["deriveBarNavValueFromUrl","path","basePath","tabs","value","hideTabs","startsWith","remainder","slice","length","seg","split","selectableTabs","getSelectableTabs","id","tab","find","t","shouldResyncBarNavProps","resolvedTabs","tabsJson","resolvedActions","actions","actionsJson","tabsIncoming","parseJsonArrayProp","actionsIncoming","fallback","Array","isArray","parsed","JSON","parse","queryWithinComponentHost","host","selector","root","shadowRoot","querySelector","getTabListFromTabGroup","tabGroupEl","tabsToMenuSections","selectedId","sections","batch","item","isTabDivider","push","items","label","isSelected","isInactive","disabled","getActiveTab","selectable","getActiveTabLabel","tabsOverflowContainer","tabListScrollWidth","containerClientWidth","collapsed","hysteresis","diff","barNavCss","BarNav","__stencil_proxyCustomElement","HTMLElement","constructor","registerHost","this","background","currentUrl","urlDerivedValue","hideTabsForDetailRoute","tabsCollapsed","menuOpen","tabLayoutCommitted","triggerLabelTruncated","headerEl","triggerEl","triggerLabelTextEl","triggerLabelObserver","menuEl","visibleTabGroupEl","probeTabGroupEl","resizeObserver","overflowCheckScheduled","intrinsicWidthRetryCount","effectiveValue","activeTabLabel","activeTabHasDot","dot","onPropsChange","syncValueFromUrl","scheduleOverflowCheck","onUrlChange","onSelectionChange","syncMenuSections","onMenuOpenChange","open","onTabsCollapsedChange","prevCollapsed","syncTriggerLabelObserver","requestAnimationFrame","undefined","queueMicrotask","focusVisibleSelectedTab","componentWillLoad","componentDidLoad","syncHostPropsIfNeeded","scheduleDeferredHostPropSync","setupOverflowObserver","componentDidRender","syncMenuAnchor","updateTriggerLabelTruncation","disconnectedCallback","disconnect","remaining","HOST_PROP_SYNC_BUDGET","tick","ResizeObserver","observe","updateTabsCollapsed","disconnectOnly","el","truncated","scrollWidth","clientWidth","getLeftZoneAvailableWidth","headerStyle","getComputedStyle","gap","parseFloat","columnGap","actionsEl","actionsWidth","offsetWidth","horizontalPadding","paddingLeft","paddingRight","spacing","getPropertyValue","trim","available","Math","max","getTabsIntrinsicWidth","tabList","scheduleIntrinsicWidthRetry","INTRINSIC_WIDTH_RETRY_MAX","intrinsicWidth","shouldCollapse","anchor","handleMenuSelect","e","detail","selectTab","String","handleMenuClose","dsTabChange","emit","focus","preventScroll","handleTabChange","handleActionChange","actionId","selected","dsActionChange","toggleTabMenu","minWidth","handleTriggerKeyDown","key","preventDefault","render","hasTabs","bgToActionBg","actionBg","h","Host","class","ref","inert","onDsChange","heading","type","onClick","onKeyDown","next","variant","name","size","color","map","action","icon","inactive","ariaLabel","side","align","onDsSelect","onDsClose"],"sources":["src/wc/components/BarNav/bar-nav-utils.ts","src/wc/components/BarNav/bar-nav-dom-utils.ts","src/wc/components/BarNav/bar-nav-tabs-menu-utils.ts","src/wc/components/BarNav/BarNav.css?tag=ds-bar-nav&encapsulation=scoped","src/wc/components/BarNav/BarNav.tsx"],"sourcesContent":["import { getSelectableTabs } from '../TabGroup/tab-item-utils';\nimport type { BarNavActionItem, BarNavTab } from './BarNav';\n\nexport interface BarNavUrlState {\n /** Tab id derived from the URL, or empty when none applies. */\n value: string;\n /** When true, tabs should be hidden (e.g. non-tab child routes like detail pages). */\n hideTabs: boolean;\n}\n\n/** Derive BarNav tab selection from `currentUrl` relative to `basePath`.\n * Mirrors motive-webapp-lab `resolveBarNavState` tab-selection semantics. */\nexport function deriveBarNavValueFromUrl(\n path: string,\n basePath: string,\n tabs: BarNavTab[],\n): BarNavUrlState {\n if (!path || !basePath) {\n return { value: '', hideTabs: false };\n }\n\n if (path !== basePath && !path.startsWith(`${basePath}/`)) {\n return { value: '', hideTabs: false };\n }\n\n const remainder = path.slice(basePath.length);\n const seg = remainder.startsWith('/') ? remainder.slice(1).split('/')[0] : '';\n const selectableTabs = getSelectableTabs(tabs);\n\n if (!seg) {\n return { value: selectableTabs[0]?.id ?? '', hideTabs: false };\n }\n\n const tab = selectableTabs.find(t => t.id === seg);\n if (tab) {\n return { value: tab.id, hideTabs: false };\n }\n\n return { value: '', hideTabs: true };\n}\n\n/** True when host array/json props have data but resolved internal state is still empty. */\nexport function shouldResyncBarNavProps(\n resolvedTabs: BarNavTab[],\n tabs: BarNavTab[],\n tabsJson: string,\n resolvedActions: BarNavActionItem[],\n actions: BarNavActionItem[],\n actionsJson: string,\n): boolean {\n const tabsIncoming = tabsJson\n ? parseJsonArrayProp(tabsJson, [])\n : (tabs ?? []);\n const actionsIncoming = actionsJson\n ? parseJsonArrayProp(actionsJson, [])\n : (actions ?? []);\n\n return (\n (resolvedTabs.length === 0 && tabsIncoming.length > 0) ||\n (resolvedActions.length === 0 && actionsIncoming.length > 0)\n );\n}\n\n/** Parse tabs/actions from either a JSON attribute string or a JS property array. */\nexport function parseJsonArrayProp<T>(value: string | T[] | undefined, fallback: T[]): T[] {\n if (Array.isArray(value)) return value;\n if (typeof value === 'string' && value !== '') {\n try {\n const parsed = JSON.parse(value);\n return Array.isArray(parsed) ? parsed : fallback;\n } catch {\n return fallback;\n }\n }\n return fallback;\n}\n","export type QueryableHost = {\n shadowRoot?: ShadowRoot | null;\n querySelector: (selectors: string) => Element | null;\n};\n\n/**\n * Query within a Stencil custom-element host (light DOM today, shadow DOM–safe).\n * Use for child nodes owned by ds-tab-group and similar components.\n */\nexport function queryWithinComponentHost(\n host: QueryableHost | null | undefined,\n selector: string,\n): HTMLElement | null {\n if (!host) return null;\n const root = host.shadowRoot ?? host;\n return root.querySelector(selector) as HTMLElement | null;\n}\n\nexport function getTabListFromTabGroup(\n tabGroupEl: QueryableHost | null | undefined,\n): HTMLElement | null {\n return queryWithinComponentHost(tabGroupEl, '[role=\"tablist\"]');\n}\n","import type { MenuSection } from '../Menu/Menu';\nimport {\n getSelectableTabs,\n isTabDivider,\n type TabItem,\n type TabItemTab,\n} from '../TabGroup/tab-item-utils';\n\n/** Map BarNav tabs to menu sections, preserving `{ type: 'divider' }` as section breaks. */\nexport function tabsToMenuSections(tabs: TabItem[], selectedId: string): MenuSection[] {\n const sections: MenuSection[] = [];\n let batch: MenuSection['items'] = [];\n\n for (const item of tabs) {\n if (isTabDivider(item)) {\n if (batch.length > 0) {\n sections.push({ items: batch });\n batch = [];\n }\n continue;\n }\n\n batch.push({\n label: item.label,\n value: item.id,\n isSelected: item.id === selectedId,\n isInactive: item.disabled,\n });\n }\n\n if (batch.length > 0) {\n sections.push({ items: batch });\n }\n\n return sections;\n}\n\nexport function getActiveTab(tabs: TabItem[], selectedId: string): TabItemTab | undefined {\n const selectable = getSelectableTabs(tabs);\n return selectable.find(tab => tab.id === selectedId) ?? selectable[0];\n}\n\nexport function getActiveTabLabel(tabs: TabItem[], selectedId: string): string {\n return getActiveTab(tabs, selectedId)?.label ?? 'Tabs';\n}\n\n/** True when tablist content exceeds the available width (with optional hysteresis). */\nexport function tabsOverflowContainer(\n tabListScrollWidth: number,\n containerClientWidth: number,\n collapsed: boolean,\n hysteresis = 2,\n): boolean {\n const diff = tabListScrollWidth - containerClientWidth;\n if (collapsed) {\n return diff > -hysteresis;\n }\n return diff > hysteresis;\n}\n",":host {\n display: block;\n}\n\n.bar-nav {\n display: flex;\n align-items: center;\n position: relative;\n height: var(--dimension-size-600);\n padding: var(--dimension-space-100);\n gap: var(--dimension-space-100);\n box-sizing: border-box;\n border-bottom: var(--dimension-stroke-width-012) solid var(--color-border-tertiary);\n}\n\n/* Background variants — mirrors ds-header pattern */\n.bg-primary {\n --_bar-nav-bg: var(--color-background-primary);\n background-color: var(--_bar-nav-bg);\n}\n.bg-secondary {\n --_bar-nav-bg: var(--color-background-secondary);\n background-color: var(--_bar-nav-bg);\n}\n.bg-transparent {\n --_bar-nav-bg: var(--color-background-primary);\n background-color: transparent;\n}\n.bg-translucent {\n --_bar-nav-bg: var(--color-background-translucent);\n background-color: var(--_bar-nav-bg);\n backdrop-filter: blur(var(--effect-blur-md));\n -webkit-backdrop-filter: blur(var(--effect-blur-md));\n}\n\n/* Collapsed — explicit spacer keeps the 8px minimum while the trigger can shrink. */\n.bar-nav--tabs-collapsed {\n display: flex;\n gap: 0;\n align-items: center;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n width: auto;\n overflow: hidden;\n}\n\n.bar-nav__between {\n flex: 1 1 0%;\n min-width: var(--dimension-space-100);\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label {\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__tab-trigger-label-text {\n display: block;\n flex: 1 1 0%;\n min-width: 0;\n}\n\n.bar-nav--tabs-collapsed .bar-nav__actions {\n flex: 0 0 auto;\n margin-left: 0;\n}\n\n/* Expanded tabs — consume space between start and actions */\n.bar-nav__left {\n position: relative;\n flex: 1 1 0%;\n min-width: 0;\n width: 0;\n display: flex;\n align-items: center;\n}\n\n.bar-nav__left ds-tab-group-nav {\n flex: 1;\n min-width: 0;\n}\n\n/* Unconstrained width so intrinsic tab row width is measurable while collapsed */\n.bar-nav__tabs-probe {\n position: absolute;\n left: 0;\n top: 0;\n visibility: hidden;\n pointer-events: none;\n overflow: visible;\n width: max-content;\n max-width: none;\n z-index: -1;\n}\n\n.bar-nav__tabs-probe ds-tab-group-nav {\n width: max-content;\n}\n\n.bar-nav__tabs-visible {\n width: 100%;\n min-width: 0;\n}\n\n/* In-flow placeholder while measuring overflow — avoids layout jump; hidden from view/accessibility. */\n.bar-nav__tabs-pending {\n flex: 1;\n min-width: 0;\n height: var(--dimension-size-400);\n visibility: hidden;\n pointer-events: none;\n}\n\n/* Collapsed tab trigger — mirrors TabGroup .tab (+ chevron when collapsed) */\n.bar-nav__tab-trigger {\n all: unset;\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 1 auto;\n min-width: 0;\n width: max-content;\n max-width: 100%;\n padding: var(--dimension-space-075);\n background-color: transparent;\n border-radius: var(--dimension-radius-025);\n cursor: pointer;\n -webkit-user-select: none;\n user-select: none;\n color: var(--color-foreground-primary);\n position: relative;\n transition: color var(--effect-motion-short-2);\n height: var(--dimension-size-400);\n --_hover-bg: var(--color-interaction-hover);\n --_pressed-bg: var(--color-interaction-pressed);\n --_dot: var(--color-foreground-bold-brand);\n --_dot-ring: var(--color-background-secondary);\n}\n\n.bar-nav__tab-trigger::after {\n content: '';\n position: absolute;\n inset: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n pointer-events: none;\n transition: none;\n z-index: 2;\n}\n\n.bar-nav__tab-trigger:hover::after {\n background: var(--_hover-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:active::after {\n background: var(--_pressed-bg);\n transition: none;\n}\n\n.bar-nav__tab-trigger:focus-visible {\n outline: var(--dimension-stroke-width-025) solid var(--color-interaction-focus);\n outline-offset: var(--dimension-space-025);\n}\n\n.bar-nav__tab-trigger--open::after {\n background: var(--_hover-bg);\n}\n\n.bar-nav__tab-trigger-label {\n position: relative;\n display: inline-flex;\n align-items: center;\n flex: 0 1 auto;\n min-width: 0;\n max-width: 100%;\n padding: 0 var(--dimension-space-025);\n overflow: hidden;\n --_fade-right: var(--dimension-space-025);\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label--truncated::after {\n content: '';\n position: absolute;\n top: 0;\n right: var(--_fade-right);\n bottom: 0;\n width: var(--dimension-size-400);\n background: linear-gradient(to right, transparent, var(--_bar-nav-bg));\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-label-text {\n display: inline-block;\n max-width: 100%;\n box-sizing: border-box;\n white-space: nowrap;\n overflow: hidden;\n vertical-align: bottom;\n}\n\n.bar-nav__tab-trigger-label-text--truncated {\n -webkit-mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n mask-image: linear-gradient(\n to right,\n #000 0,\n #000 calc(100% - var(--dimension-size-400)),\n transparent 100%\n );\n -webkit-mask-repeat: no-repeat;\n mask-repeat: no-repeat;\n -webkit-mask-size: 100% 100%;\n mask-size: 100% 100%;\n}\n\n.bar-nav__tab-trigger-label--dot {\n padding-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n --_fade-right: calc(var(--dimension-space-025) + var(--dimension-space-050));\n}\n\n.bar-nav__tab-trigger-dot {\n position: absolute;\n top: 0;\n right: 0;\n pointer-events: none;\n z-index: 1;\n}\n\n.bar-nav__tab-trigger-chevron {\n position: relative;\n flex-shrink: 0;\n z-index: 1;\n}\n\n/* Fallback heading when no tabs — matches a single (selected) tab so the area\n name shares the tab label's type token, color, height and horizontal inset.\n Inset = tab button padding (space-075, 6px) + label inset (space-025, 2px). */\n.bar-nav__heading {\n display: inline-flex;\n align-items: center;\n height: var(--dimension-size-400);\n padding-inline: var(--dimension-space-100);\n color: var(--color-foreground-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Right zone — pinned to the end; header gap is the min space from tabs/trigger */\n.bar-nav__actions {\n display: flex;\n align-items: center;\n gap: var(--dimension-space-050);\n flex: 0 0 auto;\n margin-left: auto;\n}\n","import {\n Component,\n Prop,\n Event,\n EventEmitter,\n Watch,\n State,\n h,\n Host,\n} from '@stencil/core';\nimport type { MenuItemData } from '../Menu/Menu';\nimport type { BarNavActionBackground } from '../BarNavAction/BarNavAction';\nimport type { TabItem } from '../TabGroup/tab-item-utils';\nimport {\n deriveBarNavValueFromUrl,\n parseJsonArrayProp,\n shouldResyncBarNavProps,\n} from './bar-nav-utils';\nimport {\n getTabListFromTabGroup,\n queryWithinComponentHost,\n type QueryableHost,\n} from './bar-nav-dom-utils';\nimport {\n getActiveTab,\n getActiveTabLabel,\n tabsOverflowContainer,\n tabsToMenuSections,\n} from './bar-nav-tabs-menu-utils';\n\nexport type BarNavBackground = 'primary' | 'secondary' | 'transparent' | 'translucent';\n\n/** Same shape as `TabItem` — supports `{ type: 'divider' }` between tab groups. */\nexport type BarNavTab = TabItem;\n\nexport interface BarNavActionItem {\n id: string;\n /** Icon name for <ds-icon>. */\n icon: string;\n /** Whether this action button is currently pressed/active. */\n selected?: boolean;\n /** Show a notification dot. */\n dot?: boolean;\n inactive?: boolean;\n ariaLabel?: string;\n}\n\n@Component({\n tag: 'ds-bar-nav',\n styleUrl: 'BarNav.css',\n scoped: true,\n})\nexport class BarNav {\n /**\n * Tab items for the left section.\n * Set via JS property: `el.tabs = [...]`. Replace the array reference to update.\n */\n @Prop() tabs: BarNavTab[] = [];\n\n /** JSON fallback for `tabs` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'tabs-json' }) tabsJson: string = '';\n\n /** ID of the currently active tab. Overridden when `currentUrl` + `basePath` are set. */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Action items rendered in the right section.\n * Set via JS property: `el.actions = [...]`. Replace the array reference to update.\n */\n @Prop() actions: BarNavActionItem[] = [];\n\n /** JSON fallback for `actions` — useful when framework bindings don't propagate arrays. */\n @Prop({ attribute: 'actions-json' }) actionsJson: string = '';\n\n /**\n * Fallback heading shown when no tabs are provided.\n * When tabs are present the heading is hidden.\n */\n @Prop() heading: string | undefined;\n\n /** Surface background variant. */\n @Prop() background: BarNavBackground = 'secondary';\n\n /** Section base path (e.g. `/dashboard/safety`). Used with `currentUrl` to derive `value`. */\n @Prop() basePath: string = '';\n\n /** Current route URL. When set with `basePath`, the active tab is derived automatically. */\n @Prop() currentUrl: string = '';\n\n /** Emitted when the active tab changes. Detail = tab id. */\n @Event() dsTabChange!: EventEmitter<string>;\n\n /** Emitted when an action button is toggled. Detail = { id, selected }. */\n @Event() dsActionChange!: EventEmitter<{ id: string; selected: boolean }>;\n\n @State() private resolvedTabs: BarNavTab[] = [];\n @State() private resolvedActions: BarNavActionItem[] = [];\n @State() private urlDerivedValue: string = '';\n @State() private hideTabsForDetailRoute = false;\n @State() private tabsCollapsed = false;\n @State() private menuOpen = false;\n /** When false, defer showing expanded tabs or the collapsed trigger until intrinsic width is measured (avoids a one-frame flash of the full tab row on narrow viewports). */\n @State() private tabLayoutCommitted = false;\n @State() private triggerLabelTruncated = false;\n\n private static readonly HOST_PROP_SYNC_BUDGET = 8;\n private static readonly INTRINSIC_WIDTH_RETRY_MAX = 3;\n\n private headerEl: HTMLElement | null = null;\n private triggerEl: HTMLButtonElement | null = null;\n private triggerLabelTextEl: HTMLElement | null = null;\n private triggerLabelObserver: ResizeObserver | null = null;\n private menuEl: HTMLDsMenuElement | null = null;\n private visibleTabGroupEl: QueryableHost | null = null;\n private probeTabGroupEl: QueryableHost | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private overflowCheckScheduled = false;\n private intrinsicWidthRetryCount = 0;\n\n private get effectiveValue(): string {\n if (this.currentUrl && this.basePath) {\n return this.urlDerivedValue;\n }\n return this.value;\n }\n\n private get activeTabLabel(): string {\n return getActiveTabLabel(this.resolvedTabs, this.effectiveValue);\n }\n\n private get activeTabHasDot(): boolean {\n return !!getActiveTab(this.resolvedTabs, this.effectiveValue)?.dot;\n }\n\n @Watch('tabs')\n @Watch('tabsJson')\n @Watch('actions')\n @Watch('actionsJson')\n onPropsChange() {\n this.resolvedTabs = this.tabsJson\n ? parseJsonArrayProp(this.tabsJson, [])\n : (this.tabs ?? []);\n this.resolvedActions = this.actionsJson\n ? parseJsonArrayProp(this.actionsJson, [])\n : (this.actions ?? []);\n this.syncValueFromUrl();\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n\n @Watch('currentUrl')\n @Watch('basePath')\n onUrlChange() {\n this.syncValueFromUrl();\n this.scheduleOverflowCheck();\n }\n\n @Watch('value')\n @Watch('urlDerivedValue')\n onSelectionChange() {\n this.syncMenuSections();\n this.scheduleOverflowCheck();\n }\n\n @Watch('menuOpen')\n onMenuOpenChange(open: boolean) {\n if (this.menuEl) {\n this.menuEl.open = open;\n }\n }\n\n @Watch('tabsCollapsed')\n onTabsCollapsedChange(collapsed: boolean, prevCollapsed: boolean | undefined) {\n if (!collapsed) {\n this.menuOpen = false;\n this.menuEl = null;\n this.triggerLabelTruncated = false;\n this.syncTriggerLabelObserver();\n }\n this.scheduleOverflowCheck();\n if (collapsed) {\n requestAnimationFrame(() => {\n this.scheduleOverflowCheck();\n this.syncTriggerLabelObserver();\n });\n }\n if (collapsed || prevCollapsed === undefined || prevCollapsed === collapsed) return;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n queueMicrotask(() => this.focusVisibleSelectedTab());\n }\n\n componentWillLoad() {\n this.onPropsChange();\n }\n\n componentDidLoad() {\n this.syncHostPropsIfNeeded();\n this.scheduleDeferredHostPropSync();\n this.setupOverflowObserver();\n this.scheduleOverflowCheck();\n }\n\n componentDidRender() {\n this.scheduleOverflowCheck();\n this.syncMenuAnchor();\n if (this.tabsCollapsed) {\n this.updateTriggerLabelTruncation();\n }\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.syncTriggerLabelObserver(true);\n }\n\n /** Re-resolve props assigned by the host after componentWillLoad (Angular ngAfterViewInit). */\n private syncHostPropsIfNeeded() {\n if (\n shouldResyncBarNavProps(\n this.resolvedTabs,\n this.tabs,\n this.tabsJson,\n this.resolvedActions,\n this.actions,\n this.actionsJson,\n )\n ) {\n this.onPropsChange();\n } else if (this.currentUrl && this.basePath) {\n this.syncValueFromUrl();\n }\n }\n\n /** Poll across animation frames — host props may land without triggering @Watch. */\n private scheduleDeferredHostPropSync() {\n let remaining = BarNav.HOST_PROP_SYNC_BUDGET;\n const tick = () => {\n this.syncHostPropsIfNeeded();\n if (--remaining > 0) {\n requestAnimationFrame(tick);\n }\n };\n queueMicrotask(tick);\n }\n\n private setupOverflowObserver() {\n if (typeof ResizeObserver === 'undefined' || !this.headerEl) return;\n this.resizeObserver?.disconnect();\n this.resizeObserver = new ResizeObserver(() => this.scheduleOverflowCheck());\n this.resizeObserver.observe(this.headerEl);\n }\n\n private scheduleOverflowCheck() {\n if (this.overflowCheckScheduled) return;\n this.overflowCheckScheduled = true;\n requestAnimationFrame(() => {\n this.overflowCheckScheduled = false;\n this.updateTabsCollapsed();\n this.updateTriggerLabelTruncation();\n });\n }\n\n private syncTriggerLabelObserver(disconnectOnly = false) {\n this.triggerLabelObserver?.disconnect();\n this.triggerLabelObserver = null;\n\n if (disconnectOnly || !this.tabsCollapsed || !this.triggerLabelTextEl) {\n return;\n }\n\n this.updateTriggerLabelTruncation();\n\n if (typeof ResizeObserver === 'undefined') return;\n\n this.triggerLabelObserver = new ResizeObserver(() => this.updateTriggerLabelTruncation());\n this.triggerLabelObserver.observe(this.triggerLabelTextEl);\n if (this.triggerEl) {\n this.triggerLabelObserver.observe(this.triggerEl);\n }\n }\n\n private updateTriggerLabelTruncation() {\n const el = this.triggerLabelTextEl;\n if (!el || !this.tabsCollapsed) {\n if (this.triggerLabelTruncated) {\n this.triggerLabelTruncated = false;\n }\n return;\n }\n\n const truncated = el.scrollWidth > el.clientWidth + 1;\n if (truncated !== this.triggerLabelTruncated) {\n this.triggerLabelTruncated = truncated;\n }\n }\n\n /** Width left for tabs after actions. */\n private getLeftZoneAvailableWidth(): number {\n if (!this.headerEl) return 0;\n\n const headerStyle = getComputedStyle(this.headerEl);\n const gap = parseFloat(headerStyle.columnGap || headerStyle.gap || '0') || 0;\n const actionsEl = this.headerEl.querySelector('.bar-nav__actions') as HTMLElement | null;\n const actionsWidth = actionsEl?.offsetWidth ?? 0;\n const horizontalPadding =\n (parseFloat(headerStyle.paddingLeft) || 0) + (parseFloat(headerStyle.paddingRight) || 0);\n const spacing = this.tabsCollapsed\n ? parseFloat(\n getComputedStyle(this.headerEl).getPropertyValue('--dimension-space-100').trim(),\n ) || 8\n : actionsEl\n ? gap\n : 0;\n const available =\n this.headerEl.clientWidth - horizontalPadding - actionsWidth - spacing;\n\n return Math.max(0, available);\n }\n\n private getTabsIntrinsicWidth(): number {\n const tabList = getTabListFromTabGroup(this.probeTabGroupEl);\n return tabList?.scrollWidth ?? 0;\n }\n\n private scheduleIntrinsicWidthRetry() {\n if (this.intrinsicWidthRetryCount >= BarNav.INTRINSIC_WIDTH_RETRY_MAX) return;\n this.intrinsicWidthRetryCount++;\n requestAnimationFrame(() => this.scheduleOverflowCheck());\n }\n\n private updateTabsCollapsed() {\n if (!this.headerEl || this.resolvedTabs.length === 0 || this.hideTabsForDetailRoute) {\n if (this.tabsCollapsed) {\n this.tabsCollapsed = false;\n this.menuOpen = false;\n }\n this.intrinsicWidthRetryCount = 0;\n return;\n }\n\n const intrinsicWidth = this.getTabsIntrinsicWidth();\n if (intrinsicWidth === 0) {\n this.scheduleIntrinsicWidthRetry();\n return;\n }\n this.intrinsicWidthRetryCount = 0;\n\n const shouldCollapse = tabsOverflowContainer(\n intrinsicWidth,\n this.getLeftZoneAvailableWidth(),\n this.tabsCollapsed,\n );\n\n if (shouldCollapse !== this.tabsCollapsed) {\n this.tabsCollapsed = shouldCollapse;\n if (!shouldCollapse) {\n this.menuOpen = false;\n }\n }\n }\n\n private syncMenuAnchor() {\n if (!this.menuEl || !this.triggerEl || !this.tabsCollapsed) return;\n this.menuEl.anchor = this.triggerEl;\n this.syncMenuSections();\n }\n\n private handleMenuSelect(e: Event) {\n const detail = (e as CustomEvent<MenuItemData>).detail;\n if (detail?.value !== undefined) {\n this.selectTab(String(detail.value));\n }\n this.menuOpen = false;\n }\n\n private handleMenuClose() {\n this.menuOpen = false;\n }\n\n private syncMenuSections() {\n if (!this.menuEl) return;\n this.menuEl.sections = tabsToMenuSections(this.resolvedTabs, this.effectiveValue);\n }\n\n private syncValueFromUrl() {\n if (!this.currentUrl || !this.basePath) {\n this.urlDerivedValue = '';\n this.hideTabsForDetailRoute = false;\n return;\n }\n\n const { value, hideTabs } = deriveBarNavValueFromUrl(\n this.currentUrl,\n this.basePath,\n this.resolvedTabs,\n );\n this.urlDerivedValue = value;\n this.hideTabsForDetailRoute = hideTabs;\n }\n\n private selectTab(id: string) {\n this.value = id;\n this.dsTabChange.emit(id);\n }\n\n /** Move focus to the selected tab in the visible tab group (after expand). */\n private focusVisibleSelectedTab() {\n const tab = queryWithinComponentHost(\n this.visibleTabGroupEl,\n `[data-tab-id=\"${this.effectiveValue}\"]`,\n );\n tab?.focus({ preventScroll: true });\n }\n\n private handleTabChange(e: Event) {\n this.selectTab((e as CustomEvent<string>).detail);\n }\n\n private handleActionChange(actionId: string, e: Event) {\n const selected = (e as CustomEvent<boolean>).detail;\n this.dsActionChange.emit({ id: actionId, selected });\n }\n\n private toggleTabMenu() {\n if (this.menuOpen) {\n this.menuOpen = false;\n return;\n }\n\n if (this.menuEl && this.triggerEl) {\n this.menuEl.anchor = this.triggerEl;\n this.menuEl.minWidth = `${this.triggerEl.offsetWidth}px`;\n this.syncMenuSections();\n }\n\n this.menuOpen = true;\n }\n\n private handleTriggerKeyDown(e: KeyboardEvent) {\n if (!this.tabsCollapsed) return;\n\n if (!this.menuOpen) {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n this.toggleTabMenu();\n }\n return;\n }\n\n if (e.key === 'Escape') {\n e.preventDefault();\n this.menuOpen = false;\n this.triggerEl?.focus();\n }\n }\n\n render() {\n const hasTabs = this.resolvedTabs.length > 0 && !this.hideTabsForDetailRoute;\n\n const bgToActionBg: Partial<Record<BarNavBackground, BarNavActionBackground>> = {};\n const actionBg: BarNavActionBackground | undefined = bgToActionBg[this.background];\n\n return (\n <Host>\n <header\n class={{\n 'bar-nav': true,\n [`bg-${this.background}`]: true,\n 'bar-nav--tabs-collapsed': hasTabs && this.tabsCollapsed,\n }}\n ref={el => {\n this.headerEl = el as HTMLElement;\n if (el && !this.resizeObserver) {\n this.setupOverflowObserver();\n }\n }}\n >\n {hasTabs && (\n <div class=\"bar-nav__tabs-probe\" aria-hidden=\"true\" inert>\n <ds-tab-group-nav\n ref={el => {\n this.probeTabGroupEl = el ?? null;\n if (el) {\n this.intrinsicWidthRetryCount = 0;\n this.scheduleOverflowCheck();\n }\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n />\n </div>\n )}\n\n {hasTabs && !this.tabsCollapsed && (\n <div class=\"bar-nav__left\">\n <ds-tab-group-nav\n class=\"bar-nav__tabs-visible\"\n ref={el => {\n this.visibleTabGroupEl = el ?? null;\n }}\n tabs={this.resolvedTabs}\n value={this.effectiveValue}\n onDsChange={(e: Event) => this.handleTabChange(e)}\n />\n </div>\n )}\n\n {!hasTabs && this.heading && (\n <span class=\"bar-nav__heading text-body-medium-emphasis\">{this.heading}</span>\n )}\n\n {hasTabs && this.tabsCollapsed && (\n <button\n type=\"button\"\n class={{\n 'bar-nav__tab-trigger': true,\n 'bar-nav__tab-trigger--open': this.menuOpen,\n }}\n ref={el => {\n this.triggerEl = el as HTMLButtonElement;\n }}\n aria-haspopup=\"menu\"\n aria-expanded={this.menuOpen}\n aria-label={`${this.activeTabLabel} tabs`}\n onClick={() => this.toggleTabMenu()}\n onKeyDown={(e: KeyboardEvent) => this.handleTriggerKeyDown(e)}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label': true,\n 'bar-nav__tab-trigger-label--dot': this.activeTabHasDot,\n 'bar-nav__tab-trigger-label--truncated': this.triggerLabelTruncated,\n }}\n >\n <span\n class={{\n 'bar-nav__tab-trigger-label-text': true,\n 'bar-nav__tab-trigger-label-text--truncated': this.triggerLabelTruncated,\n 'text-body-medium-emphasis': true,\n }}\n ref={el => {\n const next = el ?? null;\n if (next === this.triggerLabelTextEl) return;\n this.triggerLabelTextEl = next;\n if (this.tabsCollapsed) {\n this.syncTriggerLabelObserver();\n }\n }}\n >\n {this.activeTabLabel}\n </span>\n {this.activeTabHasDot && (\n <ds-badge\n class=\"bar-nav__tab-trigger-dot\"\n variant=\"dot\"\n background=\"var(--_dot-ring)\"\n label=\"\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n <ds-icon\n name=\"ChevronDown\"\n size=\"md\"\n color=\"inherit\"\n class=\"bar-nav__tab-trigger-chevron\"\n />\n </button>\n )}\n\n {hasTabs && this.tabsCollapsed && this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__between\" aria-hidden=\"true\" />\n )}\n\n {this.resolvedActions.length > 0 && (\n <div class=\"bar-nav__actions\">\n {this.resolvedActions.map(action => (\n <ds-bar-nav-action\n key={action.id}\n icon={action.icon}\n selected={action.selected ?? false}\n dot={action.dot ?? false}\n inactive={action.inactive}\n aria-label={action.ariaLabel ?? action.id}\n background={actionBg}\n onDsChange={(e: Event) => this.handleActionChange(action.id, e)}\n />\n ))}\n </div>\n )}\n\n </header>\n\n {hasTabs && this.tabsCollapsed && (\n <ds-menu\n ref={el => {\n this.menuEl = (el as HTMLDsMenuElement) ?? null;\n }}\n open={this.menuOpen}\n sections={tabsToMenuSections(this.resolvedTabs, this.effectiveValue)}\n side=\"bottom\"\n align=\"start\"\n onDsSelect={(e: Event) => this.handleMenuSelect(e)}\n onDsClose={() => this.handleMenuClose()}\n />\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as t,H as o,c as r,h as s,a as i,t as d}from"./index.js";import{d as e}from"./p-COsKOwZR.js";import{d as n}from"./p-
|
|
1
|
+
import{p as t,H as o,c as r,h as s,a as i,t as d}from"./index.js";import{d as e}from"./p-COsKOwZR.js";import{d as n}from"./p-DrDrPeVV.js";import{d as a}from"./p-BcuUR5Ao.js";const u=()=>`.group.sc-ds-button-group{display:inline-flex;align-items:stretch;border-radius:var(--dimension-radius-050);position:relative}.group.sc-ds-button-group::after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none}.groupElevated.sc-ds-button-group{box-shadow:var(--effect-shadow-elevated-sm)}.groupElevated.sc-ds-button-group::after{box-shadow:var(--effect-highlight-elevated-sm)}.groupFlat.sc-ds-button-group::after{box-shadow:inset 0 0 0 1px var(--color-border-tertiary)}.groupFloating.sc-ds-button-group{box-shadow:var(--effect-shadow-elevated-floating)}.groupFloating.sc-ds-button-group::after{box-shadow:var(--effect-highlight-elevated-floating)}.groupRounded.sc-ds-button-group{border-radius:var(--dimension-radius-half)}.item.sc-ds-button-group{flex-shrink:0;box-shadow:none !important;border:none !important}.item.sc-ds-button-group:active{transform:none !important}.divider.sc-ds-button-group{width:1px;flex-shrink:0;background-color:var(--color-border-tertiary);position:relative;z-index:1;margin:0 -0.5px;pointer-events:none}.dividerGhost.sc-ds-button-group{height:20px;align-self:center}.dividerGhostXS.sc-ds-button-group{height:12px}.dividerGhostSM.sc-ds-button-group{height:16px}.dividerGhostLG.sc-ds-button-group{height:24px}.item.sc-ds-button-group:hover+.dividerGhost.sc-ds-button-group,.dividerGhost.sc-ds-button-group:has(+.item:hover){opacity:0}.group.sc-ds-button-group .itemShort.sc-ds-button-group::after{border-top-left-radius:var(--dimension-radius-050) !important;border-top-right-radius:var(--dimension-radius-050) !important;border-bottom-right-radius:var(--dimension-radius-050) !important;border-bottom-left-radius:var(--dimension-radius-050) !important}.first.sc-ds-button-group{border-top-right-radius:0 !important;border-bottom-right-radius:0 !important}.last.sc-ds-button-group{border-top-left-radius:0 !important;border-bottom-left-radius:0 !important}.middle.sc-ds-button-group{border-radius:0 !important}.groupRounded.sc-ds-button-group .first.itemShort.sc-ds-button-group::after{border-top-left-radius:var(--dimension-radius-half) !important;border-bottom-left-radius:var(--dimension-radius-half) !important}.groupRounded.sc-ds-button-group .last.itemShort.sc-ds-button-group::after{border-top-right-radius:var(--dimension-radius-half) !important;border-bottom-right-radius:var(--dimension-radius-half) !important}.roundedFirstMD.sc-ds-button-group{padding-right:var(--dimension-space-100) !important}.roundedLastMD.sc-ds-button-group{padding-left:var(--dimension-space-100) !important}.roundedMidMD.sc-ds-button-group{padding-left:var(--dimension-space-100) !important;padding-right:var(--dimension-space-100) !important}.roundedFirstSM.sc-ds-button-group{padding-right:var(--dimension-space-075) !important}.roundedLastSM.sc-ds-button-group{padding-left:var(--dimension-space-075) !important}.roundedMidSM.sc-ds-button-group{padding-left:var(--dimension-space-075) !important;padding-right:var(--dimension-space-075) !important}.roundedFirstLG.sc-ds-button-group{padding-right:var(--dimension-space-150) !important}.roundedLastLG.sc-ds-button-group{padding-left:var(--dimension-space-150) !important}.roundedMidLG.sc-ds-button-group{padding-left:var(--dimension-space-150) !important;padding-right:var(--dimension-space-150) !important}`;const p=t(class t extends o{constructor(t){super();if(t!==false){this.__registerHost()}this.dsClick=r(this,"dsClick");this.items=[];this.elevation="flat";this.size="md";this.rounded=false}render(){const t=this.items;const o=t.length;const r=this.elevation;const d=r.charAt(0).toUpperCase()+r.slice(1);const e=r==="none";const n={group:true,[`group${d}`]:true,groupRounded:this.rounded};return s(i,{key:"4a503b0109a778266f4a3cd9a3f999c7f6989685"},s("div",{key:"3417c2022b0382bdd4fb917b36322e9e01b1962d",class:n,role:"group"},t.map(((t,i)=>{const d=i===0;const n=i===o-1;const a=!d&&!n;const u=t.variant??"secondary";const p=!!t.icon&&!t.label;const c=this.rounded&&!p&&this.size!=="xs";const g=this.size.toUpperCase();const m={item:true,first:d,last:n,middle:a,itemShort:e&&u==="secondary",[`roundedFirst${g}`]:!!(c&&d),[`roundedLast${g}`]:!!(c&&n),[`roundedMid${g}`]:!!(c&&a)};const b={divider:true,dividerGhost:e,dividerGhostXS:e&&this.size==="xs",dividerGhostSM:e&&this.size==="sm",dividerGhostLG:e&&this.size==="lg"};return[i>0&&s("div",{class:b,"aria-hidden":"true"}),s("ds-button",{class:m,variant:u,intent:t.intent??"none",elevation:r,size:this.size,label:t.label,rounded:this.rounded,inactive:t.inactive,href:t.href,onDsClick:()=>this.dsClick.emit(i)},t.icon&&s("ds-icon",{slot:"icon",name:t.icon}))]}))))}static get style(){return u()}},[2,"ds-button-group",{items:[16],elevation:[1],size:[1],rounded:[4]}]);function c(){if(typeof customElements==="undefined"){return}const t=["ds-button-group","ds-button","ds-icon","ds-loader"];t.forEach((t=>{switch(t){case"ds-button-group":if(!customElements.get(d(t))){customElements.define(d(t),p)}break;case"ds-button":if(!customElements.get(d(t))){e()}break;case"ds-icon":if(!customElements.get(d(t))){n()}break;case"ds-loader":if(!customElements.get(d(t))){a()}break}}))}c();const g=p;const m=c;export{g as DsButtonGroup,m as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-button-group.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{p as e,H as
|
|
1
|
+
import{p as e,H as c,c as s,h as o,a as i,t as r}from"./index.js";const t=()=>`.checkbox.sc-ds-checkbox{display:flex;align-items:center;gap:var(--dimension-space-050);padding:var(--dimension-space-075);height:var(--dimension-size-400);box-sizing:border-box;cursor:pointer;user-select:none;border-radius:var(--dimension-radius-075);transition:background-color var(--effect-motion-short-2)}.checkbox.sc-ds-checkbox:hover{background-color:var(--color-interaction-hover)}.checkbox.sc-ds-checkbox:active{background-color:var(--color-interaction-pressed)}.inactive.sc-ds-checkbox{cursor:not-allowed;opacity:0.5;pointer-events:none}.box.sc-ds-checkbox{width:20px;height:20px;flex-shrink:0;border:1.5px solid var(--color-foreground-secondary);border-radius:var(--dimension-radius-050);display:flex;align-items:center;justify-content:center;box-sizing:border-box;transition:all var(--effect-motion-short-2)}.box--marked.sc-ds-checkbox{background-color:var(--color-foreground-primary);border-color:var(--color-foreground-primary)}.checkmark.sc-ds-checkbox{color:var(--color-foreground-on-bold-background-primary);font-size:14px;line-height:1;font-weight:700}.checkbox__label.sc-ds-checkbox{flex:1;min-width:0}`;let a=0;const n=e(class e extends c{constructor(e){super();if(e!==false){this.__registerHost()}this.dsChange=s(this,"dsChange");this.labelId=`ds-checkbox-label-${++a}`;this.checked=false;this.indeterminate=false;this.inactive=false;this.handleActivate=()=>{if(this.inactive)return;this.checked=!this.checked;this.dsChange.emit(this.checked)};this.handleKeyDown=e=>{if(e.key===" "||e.key==="Enter"){e.preventDefault();this.handleActivate()}}}render(){const e=this.checked||this.indeterminate;return o(i,{key:"5e3a07e18c04d2cfe30c1023ee86e5a26c2d7da9",role:"checkbox","aria-checked":this.indeterminate?"mixed":String(this.checked),"aria-disabled":this.inactive||undefined,"aria-labelledby":this.labelId,tabIndex:this.inactive?-1:0,class:{checkbox:true,inactive:this.inactive},onClick:this.handleActivate,onKeyDown:this.handleKeyDown},o("span",{key:"cd702c8a610fbbad02bf4f3d940ffdcaefe0cbd8",class:{box:true,"box--marked":e}},e&&o("span",{key:"51912de7f7e2a4a742825a95bfbc3b4c0a082860",class:"checkmark","aria-hidden":"true"},this.indeterminate?"−":"✓")),o("span",{key:"d902e037763036bc8a8c384029cf1d38a6f6ebac",id:this.labelId,class:"text-body-medium checkbox__label"},this.label))}static get style(){return t()}},[2,"ds-checkbox",{label:[1],checked:[1028],indeterminate:[4],inactive:[4]}]);function d(){if(typeof customElements==="undefined"){return}const e=["ds-checkbox"];e.forEach((e=>{switch(e){case"ds-checkbox":if(!customElements.get(r(e))){customElements.define(r(e),n)}break}}))}d();const h=n;const b=d;export{h as DsCheckbox,b as defineCustomElement};
|
|
2
2
|
//# sourceMappingURL=ds-checkbox.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Components, JSX } from "../types/components";
|
|
2
2
|
|
|
3
|
-
interface
|
|
4
|
-
export const
|
|
5
|
-
prototype:
|
|
6
|
-
new ():
|
|
3
|
+
interface DsChip extends Components.DsChip, HTMLElement {}
|
|
4
|
+
export const DsChip: {
|
|
5
|
+
prototype: DsChip;
|
|
6
|
+
new (): DsChip;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* Used to define this component and all nested components recursively.
|