@skdx/docs-kit 0.39.0 → 0.40.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/dist/data/angular-inputs.json +1 -1
- package/dist/data/api-manifest.json +1 -1
- package/dist/shared/contracts/accordion.js +1 -1
- package/dist/shared/contracts/alert.js +1 -1
- package/dist/shared/contracts/autocomplete.d.ts +1 -1
- package/dist/shared/contracts/autocomplete.js +1 -1
- package/dist/shared/contracts/avatar.js +1 -1
- package/dist/shared/contracts/breadcrumb.js +1 -1
- package/dist/shared/contracts/button.js +1 -1
- package/dist/shared/contracts/calendar.js +1 -1
- package/dist/shared/contracts/card.js +1 -1
- package/dist/shared/contracts/carousel.js +1 -1
- package/dist/shared/contracts/checkbox-card.js +1 -1
- package/dist/shared/contracts/checkbox-group.js +1 -1
- package/dist/shared/contracts/collapsible.js +1 -1
- package/dist/shared/contracts/combobox.js +1 -1
- package/dist/shared/contracts/command.js +1 -1
- package/dist/shared/contracts/dashboard-layout.js +1 -1
- package/dist/shared/contracts/date-picker.js +1 -1
- package/dist/shared/contracts/dialog.d.ts +1 -1
- package/dist/shared/contracts/dialog.js +1 -1
- package/dist/shared/contracts/drawer.d.ts +1 -1
- package/dist/shared/contracts/drawer.js +1 -1
- package/dist/shared/contracts/field.js +1 -1
- package/dist/shared/contracts/file-upload.js +1 -1
- package/dist/shared/contracts/floating-panel.js +1 -1
- package/dist/shared/contracts/form.js +1 -1
- package/dist/shared/contracts/image.js +1 -1
- package/dist/shared/contracts/listbox.js +1 -1
- package/dist/shared/contracts/loading-overlay.js +1 -1
- package/dist/shared/contracts/mentions.js +1 -1
- package/dist/shared/contracts/menu.js +1 -1
- package/dist/shared/contracts/menubar.js +1 -1
- package/dist/shared/contracts/navigation-menu.js +1 -1
- package/dist/shared/contracts/pagination.js +1 -1
- package/dist/shared/contracts/password-input.js +1 -1
- package/dist/shared/contracts/popover.js +1 -1
- package/dist/shared/contracts/progress.js +1 -1
- package/dist/shared/contracts/qr-code.js +1 -1
- package/dist/shared/contracts/radio-card.js +1 -1
- package/dist/shared/contracts/radio-group.js +1 -1
- package/dist/shared/contracts/rating.js +1 -1
- package/dist/shared/contracts/resizable.js +1 -1
- package/dist/shared/contracts/scroll-area.js +1 -1
- package/dist/shared/contracts/select.js +1 -1
- package/dist/shared/contracts/slider.js +1 -1
- package/dist/shared/contracts/speed-dial.js +1 -1
- package/dist/shared/contracts/split-button.js +1 -1
- package/dist/shared/contracts/stepper.js +1 -1
- package/dist/shared/contracts/switch.js +1 -1
- package/dist/shared/contracts/table.js +3 -1
- package/dist/shared/contracts/tabs.js +1 -1
- package/dist/shared/contracts/tag-group.js +1 -1
- package/dist/shared/contracts/tags-input.js +1 -1
- package/dist/shared/contracts/text-field.js +1 -1
- package/dist/shared/contracts/textarea.js +1 -1
- package/dist/shared/contracts/timeline.js +1 -1
- package/dist/shared/contracts/toast.js +9 -1
- package/dist/shared/contracts/toolbar.js +1 -1
- package/dist/shared/contracts/tour.js +1 -1
- package/dist/shared/contracts/transfer.js +1 -1
- package/dist/shared/contracts/tree-select.js +1 -1
- package/dist/shared/contracts/tree.js +1 -1
- package/dist/shared/contracts/types.d.ts +2 -0
- package/dist/shared/contracts/workspace-switcher.js +1 -1
- package/dist/shared/core/field-core.d.ts +2 -0
- package/dist/shared/core/field-core.js +1 -1
- package/dist/skins-src/_foundation-fallback.css +2 -1
- package/dist/skins-src/components/_actuator.css +1 -1
- package/dist/skins-src/components/_card-control.css +1 -1
- package/dist/skins-src/components/_collection.css +2 -2
- package/dist/skins-src/components/_overlay.css +1 -1
- package/dist/skins-src/components/_trigger.css +1 -1
- package/dist/skins-src/components/accordion.css +1 -1
- package/dist/skins-src/components/alert.css +2 -2
- package/dist/skins-src/components/autocomplete.css +1 -1
- package/dist/skins-src/components/avatar.css +1 -1
- package/dist/skins-src/components/badge.css +1 -1
- package/dist/skins-src/components/button.css +1 -1
- package/dist/skins-src/components/calendar.css +8 -6
- package/dist/skins-src/components/card.css +1 -1
- package/dist/skins-src/components/carousel.css +1 -1
- package/dist/skins-src/components/chat-composer.css +1 -1
- package/dist/skins-src/components/chat-message.css +1 -1
- package/dist/skins-src/components/checkbox-card.css +2 -2
- package/dist/skins-src/components/checkbox.css +1 -1
- package/dist/skins-src/components/clipboard.css +2 -2
- package/dist/skins-src/components/color-picker.css +4 -4
- package/dist/skins-src/components/combobox.css +2 -2
- package/dist/skins-src/components/command.css +1 -1
- package/dist/skins-src/components/dashboard-layout.css +1 -1
- package/dist/skins-src/components/date-field.css +2 -2
- package/dist/skins-src/components/dialog.css +4 -4
- package/dist/skins-src/components/drawer.css +9 -9
- package/dist/skins-src/components/editable.css +3 -3
- package/dist/skins-src/components/file-upload.css +4 -4
- package/dist/skins-src/components/floating-panel.css +1 -1
- package/dist/skins-src/components/forgot-password-page.css +1 -1
- package/dist/skins-src/components/form-section.css +1 -1
- package/dist/skins-src/components/form.css +12 -2
- package/dist/skins-src/components/image.css +1 -1
- package/dist/skins-src/components/kbd.css +1 -1
- package/dist/skins-src/components/link.css +1 -1
- package/dist/skins-src/components/listbox.css +1 -1
- package/dist/skins-src/components/mentions.css +1 -1
- package/dist/skins-src/components/menubar.css +2 -2
- package/dist/skins-src/components/navigation-menu.css +1 -1
- package/dist/skins-src/components/number-field.css +1 -1
- package/dist/skins-src/components/onboarding-checklist.css +1 -1
- package/dist/skins-src/components/pagination.css +2 -2
- package/dist/skins-src/components/password-input.css +80 -16
- package/dist/skins-src/components/pin-input.css +2 -2
- package/dist/skins-src/components/popover.css +1 -1
- package/dist/skins-src/components/qr-code.css +2 -2
- package/dist/skins-src/components/radio-card.css +1 -1
- package/dist/skins-src/components/reset-password-page.css +1 -1
- package/dist/skins-src/components/select.css +3 -3
- package/dist/skins-src/components/sign-in-page.css +1 -1
- package/dist/skins-src/components/sign-up-page.css +1 -1
- package/dist/skins-src/components/skeleton.css +1 -1
- package/dist/skins-src/components/skip-link.css +1 -1
- package/dist/skins-src/components/speed-dial.css +3 -3
- package/dist/skins-src/components/stat-card.css +6 -1
- package/dist/skins-src/components/stepper.css +3 -1
- package/dist/skins-src/components/switch.css +21 -1
- package/dist/skins-src/components/table.css +4 -4
- package/dist/skins-src/components/tags-input.css +2 -2
- package/dist/skins-src/components/text-field.css +26 -21
- package/dist/skins-src/components/text.css +1 -1
- package/dist/skins-src/components/textarea.css +1 -1
- package/dist/skins-src/components/time-field.css +2 -2
- package/dist/skins-src/components/toast.css +2 -2
- package/dist/skins-src/components/toggle-group.css +3 -3
- package/dist/skins-src/components/toggle.css +1 -1
- package/dist/skins-src/components/toolbar.css +2 -2
- package/dist/skins-src/components/tree-select.css +2 -2
- package/dist/skins-src/components/tree.css +1 -1
- package/dist/skins-src/components/usage-card.css +1 -1
- package/dist/skins-src/components/user-menu.css +1 -1
- package/dist/skins-src/components/verification-page.css +1 -1
- package/dist/skins-src/components/workspace-switcher.css +2 -2
- package/package.json +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_DATA_ATTRIBUTES as e}from"./styling-hooks.js";var a={name:"Tree",purpose:"A hierarchical list following the WAI-ARIA treeview pattern. The root owns expanded/selected/active-node state; nodes with a nested TreeGroup are expandable.",props:[{name:"selectionMode",type:"'single' | 'multiple' | 'none'",defaultValue:"'single'",required:!1,description:'"none" makes the tree expand/collapse-only, with no node selection. "single" means at most one id on each axis \u2014 `selectedIds` and `checkedIds` hold one entry or none \u2014 because a checked set left to derive from selection can never outgrow it. "multiple" is what lifts that cap, and the only mode selectionPropagation means anything in.'},{name:"expandedIds",type:"string[]",required:!1,description:"Expanded node ids, for controlled usage."},{name:"defaultExpandedIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded node ids, for uncontrolled usage."},{name:"selectedIds",type:"string[]",required:!1,description:"Selected node ids, for controlled usage."},{name:"defaultSelectedIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially selected node ids, for uncontrolled usage."},{name:"checkedIds",type:"string[]",required:!1,description:'Checked node ids, for controlled usage. A second axis from `selectedIds`, which means row highlight only \u2014 a tri-state checkbox tree has to be able to say "highlighted but unticked", and one set cannot. Omit it and `aria-checked` keeps deriving from `selectedIds` exactly as before, so an existing tree is unaffected; supply it and the two come apart.'},{name:"defaultCheckedIds",type:"string[]",required:!1,description:"Initially checked node ids, for uncontrolled usage. Omit it, like `checkedIds`, to keep checked state derived from selection."},{name:"selectionPropagation",type:"'none' | 'descendants'",defaultValue:"'none'",required:!1,description:'Turns the tree into a tri-state checkbox tree: toggling a node applies to its whole subtree. Only meaningful with selectionMode="multiple". Propagation reaches every descendant the tree has ever rendered, not only the mounted ones. A collapsed group is unmounted, so its parent stays reporting "mixed" rather than silently dropping to "false". A branch whose children have never been mounted \u2014 declared through hasChildren before loadChildren runs \u2014 reports its own selected state until first expanded.'},{name:"loadChildren",type:"(nodeId: string) => void | Promise<void>",required:!1,description:`Loads a node's children the first time it is expanded. The node carries aria-busy="true" and data-loading until the returned promise settles; on resolution getLoadedLabel is announced through the live region. A rejection clears the busy state and leaves the node eligible to retry. The node has to be declared a branch through the item's hasChildren to be expandable before anything is loaded, since nothing has been rendered under it yet.`},{name:"getLoadedLabel",type:"(nodeId: string) => string",defaultValue:"defaultGetLoadedLabel",required:!1,description:`Formats the message announced when a lazily-loaded node's children arrive. Return an empty string to announce nothing. The default announces the node's own id followed by "loaded", e.g. "src loaded".`},{name:"disabledBehavior",type:"'all' | 'selection'",defaultValue:"'all'",required:!1,description:`What an item's disabled takes away. 'all' makes the node inert: arrows step over it. 'selection' keeps it in the roving-focus order and typeahead list, refusing selection only, which is the only way its aria-disabled="true" is heard. Choose 'selection' when the reason a node is disabled is itself information the user needs.`},{name:"collection",type:"ReadonlyArray<{ nodeId: string; label?: string; disabled?: boolean; hasChildren?: boolean; textValue?: string; children?: TreeNode[] }>",required:!1,description:'Hierarchical data the tree renders instead of TreeItem/TreeGroup children. The source of truth when supplied; children slot is ignored. Node ids must be unique across the collection. A node without children is a leaf unless hasChildren declares it a branch whose children are still unloaded (aria-expanded="false"). The rendered structure is identical to hand-written composition. This is the same shape TreeSelect takes, spelled with nodeId rather than value.'},{name:"renderLabel",type:"(node: TreeNode) => unknown",required:!1,frameworks:["react","vue","svelte","webComponents"],exception:"render-prop",frameworksReason:"Angular ships this member as `labelTemplate`, a TemplateRef taking the same context \u2014 a render function has no Angular equivalent. Declared exactly as the sibling member on TreeSelect's Tree part is, and for the same reason: the gate matches member names literally and has no per-prop rename mechanism.",description:"Renders a collection node's content \u2014 label and any indicator. Ignored without collection, since composition already puts the consumer in charge. Defaults to the node's label, falling back to its nodeId. In Angular this is `labelTemplate`, a TemplateRef taking the same context."},{name:"expandOnClick",type:"boolean",defaultValue:"true",required:!1,description:"Whether clicking a branch row toggles its expansion as well as selecting it. false leaves expansion to the item indicator chevron alone. Keyboard ArrowRight/ArrowLeft are unaffected."}],events:[{name:"expanded-ids-change",description:"Fires with the new set of expanded ids.",detail:"string[]"},{name:"selected-ids-change",description:"Fires with the new set of selected ids.",detail:"string[]"},{name:"checked-ids-change",detail:"string[]",description:"Fires with the new set of checked ids. Only fires once the tree has a checked axis of its own \u2014 that is, when `checkedIds` or `defaultCheckedIds` is supplied."},{name:"activate",description:'Fires with the node id when a node is activated \u2014 Enter, or a pointer click on the row. Activation is not selection: APG separates Enter ("performs its default action") from Space ("toggles the selection state"), and a file tree needs both, one to open the file and one to tick it. Space never fires this. Selection still happens on both keys, so the two axes stay independent rather than one replacing the other.',detail:"string"},{name:"load-error",description:"Fires with { nodeId, error } when a node's loadChildren promise rejects. Without it a failed load is indistinguishable from an empty branch: the busy flag clears, nothing is announced, and the node sits expanded with no children and no explanation. The rejection is not rethrown \u2014 a floating unhandled rejection would be a worse failure mode \u2014 so this is the only place a retry affordance or a failure announcement can come from. The node is left eligible to retry.",detail:"{ nodeId: string; error: unknown }"}],parts:[{name:"Item",description:'One role="treeitem" node, carrying aria-level, aria-posinset/aria-setsize, and \u2014 on a branch \u2014 aria-expanded and data-state.',props:[{name:"nodeId",type:"string",required:!0,description:"This node's identity in every piece of state the root owns \u2014 expandedIds, selectedIds, the active (tabbable) node, the loading set and the parent/child hierarchy the tri-state derives from \u2014 and the value published on data-skdx-tree-node-id. Required rather than defaulted: an id the tree invented would change on every remount, so nothing controlled could ever address the node."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:`Excludes this node from selection and keyboard activation. Under the root's default disabledBehavior="all", takes it out of the roving-focus order so arrows step over it. It stays announced as aria-disabled="true", explaining why focus never arrives. Not inherited: the node is still rendered, its subtree still expands, and its descendants stay fully navigable and selectable.`},{name:"textValue",type:"string",required:!1,description:"The text typeahead matches this node against, instead of its rendered label, published as data-text-value. Use it when the label is not plain text \u2014 an icon plus a truncated name, a highlighted filter match \u2014 or when the searchable text differs from the visible one. Omitted, the node's own text is used, excluding its aria-hidden indicator and its nested group."},{name:"hasChildren",type:"boolean",required:!1,description:"Declares whether this node is a branch, overriding the nested-group scan. true makes the node report aria-expanded and accept ArrowRight with no group mounted at all, which a lazily-loaded branch needs. false forces the node to read as a leaf even with a group among its children. Inferred from the presence of a nested group when omitted."}]},{name:"Group",description:`One role="group" container for a branch's child items, rendered inside the TreeItem it belongs to. It is unmounted while its branch is collapsed rather than hidden, which is what makes the roving tabindex span currently-visible items for free. Publishes data-state expanded/collapsed, the hook a force-mounted group is styled by while its branch is closed.`,props:[{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,description:`Keeps the group mounted while its branch is collapsed, for exit animations. The skin then hides it on data-state="collapsed", since painting it would contradict the branch's aria-expanded="false"; override that rule to animate the exit. A force-mounted group's items stay registered, counting towards their parent's tri-state.`}]},{name:"ItemIndicator",description:"A branch's expand/collapse affordance, rendered inside the TreeItem it belongs to. It mirrors its item's data-state (expanded/collapsed) so the skin can rotate one glyph rather than swap two, and clicking it toggles the branch without selecting the row. Decorative to assistive technology: the item's own aria-expanded already carries the state. A collection tree derives one for every branch, so a hand-composed tree and a collection tree have the same affordance.",props:[]}],slots:[{name:"default",description:"Root content \u2014 TreeItems. Ignored while `collection` is supplied, which is then the source of truth."},{name:"indicator",description:"A TreeItem's expand/collapse affordance (e.g. a chevron)."}],states:["expanded","collapsed","selected","unselected","loading","indeterminate"],controlledUncontrolled:"Expansion and selection each support both controlled and uncontrolled usage, independently of one another.",formBehavior:"Not applicable \u2014 Tree does not participate in forms. Angular alone additionally registers as a ControlValueAccessor, which is an extension of that framework rather than a capability the other four owe; see frameworkExtensions.",validationBehavior:"Not applicable \u2014 Tree carries no value and participates in no validation.",accessibility:{role:"tree (root), treeitem (TreeItem), group (TreeGroup)",keyboard:[{key:"ArrowUp/ArrowDown",behavior:"Moves focus between currently-visible items, no wrap."},{key:"Home/End",behavior:"Moves focus to the first/last currently-visible item."},{key:"ArrowRight",behavior:"Expands a collapsed branch, or moves focus to its first child if already expanded. A node declared a branch through the item's hasChildren counts as one with nothing rendered under it yet, which is what lets ArrowRight trigger loadChildren."},{key:"ArrowLeft",behavior:"Collapses an expanded node with children, or moves focus to its parent."},{key:"Printable characters",behavior:"Typeahead: moves focus to the next currently-visible node whose label starts with what was typed, wrapping around. A 1s buffer accumulates characters into one search; repeating a single letter cycles through the nodes starting with it. A node's label is its `data-text-value` when it has one, otherwise its own text \u2014 excluding its aria-hidden TreeItemIndicator and any nested TreeGroup, so a chevron glyph and a child's text never enter the match. Typeahead moves focus only, it never selects; Space is claimed by selection, so it never starts a search."},{key:"*",behavior:"Expands every collapsed sibling of the focused node \u2014 the nodes at the same level under the same parent. Focus does not move."},{key:"Shift+ArrowUp/Shift+ArrowDown",behavior:`selectionMode="multiple" only: moves focus to the previous/next visible node and toggles that node's selection, extending the selection as focus travels. Plain ArrowUp/ArrowDown elsewhere.`},{key:"Shift+Space",behavior:'selectionMode="multiple" only: selects the contiguous run of visible nodes between the most recently *selected* node and the focused one, inclusive, in one update. The anchor is the last node selected, not the last node focused, so walking with plain arrows and then pressing Shift+Space extends from wherever the selection last landed \u2014 which is the point of the binding. With no anchor yet (or one that has since been collapsed away) it selects the focused node alone, exactly as Space would.'},{key:"Ctrl+ArrowUp/Ctrl+ArrowDown",behavior:"Identical to plain ArrowUp/ArrowDown: moves focus to the previous/next visible node without touching the selection. There is no separate handler, and none is needed \u2014 selection never follows focus in this tree, so the plain arrows already do what the modifier asks for. It is listed because a user arriving from APG's alternative multi-select model, where the plain arrows *do* move the selection, will reach for it; and because a Control-modified arrow must not start a typeahead search, which is the one thing that would otherwise differ."},{key:"Control+Shift+Home/Control+Shift+End",behavior:`selectionMode="multiple" only: moves focus to the first/last visible node and selects every node from the previously focused one through it. This is APG's binding. The bare Shift+Home/Shift+End form is kept as an alias for one release \u2014 it is what the component shipped with \u2014 but is not the documented one. Plain Home/End moves focus only.`},{key:"Ctrl+A",behavior:'selectionMode="multiple" only: selects every currently-visible node, or clears the selection when every one of them is already selected. Focus does not move. The toggle matters because the same chord is the only affordance a user has for undoing it. The scope is the *rendered* tree rather than the whole tree, which is as far as it can reach: a collapsed branch is unmounted, and the root holds no list of what is inside one.'},{key:"Enter",behavior:'Selects the focused node *and* fires the activate event. APG: "Activates a node, i.e., performs its default action."'},{key:"Space",behavior:'Selects the focused node and nothing else \u2014 never fires activate. APG: "Toggles the selection state of the focused node."'}],ariaAttributes:['aria-label or aria-labelledby on the root, supplied by the consumer \u2014 normative for role="tree" (see `namingRequirement`)','aria-multiselectable on the root when selectionMode is "multiple"',"each item's aria-level reflects its nesting depth","aria-setsize and aria-posinset (1-based) on every item, counting its siblings at the same level under the same parent \u2014 required rather than optional here because collapsed subtrees are unmounted, so assistive tech cannot infer a set it cannot see","author-supplied aria-level, aria-posinset and aria-setsize override the computed ones. This is contracted, not incidental: it is what the virtualization pattern depends on \u2014 a windowed tree renders a slice of the nodes and has to state the real positions itself \u2014 and it is exactly the case APG requires the attributes for. Every framework spreads consumer attributes after its own, and a Tree item given an explicit aria-posinset must render that value",`the computed pair is measured from the rendered DOM after mount, so server-rendered HTML carries neither. A non-hydrated tree \u2014 an Astro island, an RSC subtree \u2014 must supply them itself through the override above, which is the same instruction the virtualization pattern already gives. There is no equivalent of the roving tab stop's "every item is a tab stop until the effect runs" fallback here: a guessed position is a wrong position, and a wrong "3 of 7" is worse than none`,'aria-selected reflects selection unless selectionMode is "none" \u2014 or selectionPropagation is "descendants", where aria-checked carries the state instead and aria-selected is omitted entirely',"aria-expanded is set only on branch items \u2014 those with a nested TreeGroup, plus those declared as branches through the item's hasChildren, which is how a lazy branch announces itself before its children exist",'aria-busy="true" on an item whose loadChildren call is still pending','aria-checked (true/false/"mixed") on every item when selectionPropagation is "descendants" \u2014 never alongside aria-selected: APG allows either, and on a parent whose children are partly selected the two contradict each other ("false" and "mixed" at once)'],namingRequirement:`The root must carry an accessible name via aria-label or aria-labelledby, supplied by the consumer. This is normative rather than advisory \u2014 APG: "The element with role tree has either a visible label referenced by aria-labelledby or a value specified for aria-label." No prop is needed, because passthrough already carries both attributes in all five packages; and nothing inside the Tree can supply it, since role="tree" is name-from-author only and the node labels inside it name the tree no more than a list's items name the list. An unnamed tree announces as a bare "tree", which is indistinguishable from every other tree on the page.`,focusManagement:'Single tab stop with roving tabindex over currently-visible items only \u2014 collapsed subtrees are unmounted, not merely hidden, so they are naturally excluded (under disabledBehavior="selection" the disabled ones stay in). The stop is seeded from the first rendered id present in selectedIds, falling back to the first rendered id \u2014 APG: "If a node is selected before the tree receives focus, focus is set on the selected node", and for a multi-select tree "focus is set on the first selected node". It is re-seeded by the same rule whenever the item holding it is removed, so collapsing or unmounting the focused branch cannot leave the tree with no tabbable item. Only the innermost treeitem under the pointer acts on a click: items nest, so a click on a leaf also reaches every ancestor handler, which would otherwise select and collapse the whole branch above it.'},styling:{cssParts:["root","item","group","item-indicator"],dataAttributes:[...e,"data-state","data-disabled","data-loading","data-checked","data-text-value","data-skdx-tree-node-id","data-skdx-tree-parent-id"],cssCustomProperties:["--skdx-tree-node-depth"]},publicMethods:[{name:"invalidate",signature:"(nodeId?: string): void",description:"Clears the loaded marker on a node so the next expansion fetches again. With nodeId, clears that node and every child it has ever rendered; omitted, clears the whole tree. The consumer owns fetching and caching."}],frameworkExtensions:[{framework:"angular",name:"ControlValueAccessor",type:"ControlValueAccessor",description:"Registers the tree as a Reactive Forms control so [(ngModel)] and formControlName carry the selection. It adds one behaviour no other package has: setDisabledState() disables the whole tree, emitting aria-disabled and data-disabled on the root and refusing selection changes, select-many and select-all. Angular-only because Reactive Forms exists nowhere else \u2014 the other four reach the same place through the controlled `selectedIds` prop and its change event, which Tree already declares."}]};export{a as treeContract};
|
|
1
|
+
import{ROOT_DATA_ATTRIBUTES as e}from"./styling-hooks.js";var a={name:"Tree",purpose:"A hierarchical list following the WAI-ARIA treeview pattern. The root owns expanded/selected/active-node state; nodes with a nested TreeGroup are expandable.",props:[{name:"selectionMode",type:"'single' | 'multiple' | 'none'",defaultValue:"'single'",required:!1,description:'"none" makes the tree expand/collapse-only, with no node selection. "single" means at most one id on each axis \u2014 `selectedIds` and `checkedIds` hold one entry or none \u2014 because a checked set left to derive from selection can never outgrow it. "multiple" is what lifts that cap, and the only mode selectionPropagation means anything in.'},{name:"expandedIds",type:"string[]",required:!1,description:"Expanded node ids, for controlled usage."},{name:"defaultExpandedIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially expanded node ids, for uncontrolled usage."},{name:"selectedIds",type:"string[]",required:!1,description:"Selected node ids, for controlled usage."},{name:"defaultSelectedIds",type:"string[]",defaultValue:"[]",required:!1,description:"Initially selected node ids, for uncontrolled usage."},{name:"checkedIds",type:"string[]",required:!1,description:'Checked node ids, for controlled usage. A second axis from `selectedIds`, which means row highlight only \u2014 a tri-state checkbox tree has to be able to say "highlighted but unticked", and one set cannot. Omit it and `aria-checked` keeps deriving from `selectedIds` exactly as before, so an existing tree is unaffected; supply it and the two come apart.'},{name:"defaultCheckedIds",type:"string[]",required:!1,description:"Initially checked node ids, for uncontrolled usage. Omit it, like `checkedIds`, to keep checked state derived from selection."},{name:"selectionPropagation",type:"'none' | 'descendants'",defaultValue:"'none'",required:!1,description:'Turns the tree into a tri-state checkbox tree: toggling a node applies to its whole subtree. Only meaningful with selectionMode="multiple". Propagation reaches every descendant the tree has ever rendered, not only the mounted ones. A collapsed group is unmounted, so its parent stays reporting "mixed" rather than silently dropping to "false". A branch whose children have never been mounted \u2014 declared through hasChildren before loadChildren runs \u2014 reports its own selected state until first expanded.'},{name:"loadChildren",type:"(nodeId: string) => void | Promise<void>",required:!1,description:`Loads a node's children the first time it is expanded. The node carries aria-busy="true" and data-loading until the returned promise settles; on resolution getLoadedLabel is announced through the live region. A rejection clears the busy state and leaves the node eligible to retry. The node has to be declared a branch through the item's hasChildren to be expandable before anything is loaded, since nothing has been rendered under it yet.`},{name:"getLoadedLabel",type:"(nodeId: string) => string",defaultValue:"defaultGetLoadedLabel",required:!1,description:`Formats the message announced when a lazily-loaded node's children arrive. Return an empty string to announce nothing. The default announces the node's own id followed by "loaded", e.g. "src loaded".`},{name:"disabledBehavior",type:"'all' | 'selection'",defaultValue:"'all'",required:!1,description:`What an item's disabled takes away. 'all' makes the node inert: arrows step over it. 'selection' keeps it in the roving-focus order and typeahead list, refusing selection only, which is the only way its aria-disabled="true" is heard. Choose 'selection' when the reason a node is disabled is itself information the user needs.`},{name:"collection",type:"ReadonlyArray<{ nodeId: string; label?: string; disabled?: boolean; hasChildren?: boolean; textValue?: string; children?: TreeNode[] }>",required:!1,description:'Hierarchical data the tree renders instead of TreeItem/TreeGroup children. The source of truth when supplied; children slot is ignored. Node ids must be unique across the collection. A node without children is a leaf unless hasChildren declares it a branch whose children are still unloaded (aria-expanded="false"). The rendered structure is identical to hand-written composition. This is the same shape TreeSelect takes, spelled with nodeId rather than value.'},{name:"renderLabel",type:"(node: TreeNode) => unknown",required:!1,frameworks:["react","vue","svelte","webComponents"],exception:"render-prop",frameworksReason:"Angular ships this member as `labelTemplate`, a TemplateRef taking the same context \u2014 a render function has no Angular equivalent. Declared exactly as the sibling member on TreeSelect's Tree part is, and for the same reason: the gate matches member names literally and has no per-prop rename mechanism.",description:"Renders a collection node's content \u2014 label and any indicator. Ignored without collection, since composition already puts the consumer in charge. Defaults to the node's label, falling back to its nodeId. In Angular this is `labelTemplate`, a TemplateRef taking the same context."},{name:"expandOnClick",type:"boolean",defaultValue:"true",required:!1,description:"Whether clicking a branch row toggles its expansion as well as selecting it. false leaves expansion to the item indicator chevron alone. Keyboard ArrowRight/ArrowLeft are unaffected."}],events:[{name:"expanded-ids-change",description:"Fires with the new set of expanded ids.",detail:"string[]"},{name:"selected-ids-change",description:"Fires with the new set of selected ids.",detail:"string[]"},{name:"checked-ids-change",detail:"string[]",description:"Fires with the new set of checked ids. Only fires once the tree has a checked axis of its own \u2014 that is, when `checkedIds` or `defaultCheckedIds` is supplied."},{name:"activate",description:'Fires with the node id when a node is activated \u2014 Enter, or a pointer click on the row. Activation is not selection: APG separates Enter ("performs its default action") from Space ("toggles the selection state"), and a file tree needs both, one to open the file and one to tick it. Space never fires this. Selection still happens on both keys, so the two axes stay independent rather than one replacing the other.',detail:"string"},{name:"load-error",description:"Fires with { nodeId, error } when a node's loadChildren promise rejects. Without it a failed load is indistinguishable from an empty branch: the busy flag clears, nothing is announced, and the node sits expanded with no children and no explanation. The rejection is not rethrown \u2014 a floating unhandled rejection would be a worse failure mode \u2014 so this is the only place a retry affordance or a failure announcement can come from. The node is left eligible to retry.",detail:"{ nodeId: string; error: unknown }"}],parts:[{name:"Item",description:'One role="treeitem" node, carrying aria-level, aria-posinset/aria-setsize, and \u2014 on a branch \u2014 aria-expanded and data-state.',props:[{name:"nodeId",type:"string",required:!0,description:"This node's identity in every piece of state the root owns \u2014 expandedIds, selectedIds, the active (tabbable) node, the loading set and the parent/child hierarchy the tri-state derives from \u2014 and the value published on data-skdx-tree-node-id. Required rather than defaulted: an id the tree invented would change on every remount, so nothing controlled could ever address the node."},{name:"disabled",type:"boolean",defaultValue:"false",required:!1,description:`Excludes this node from selection and keyboard activation. Under the root's default disabledBehavior="all", takes it out of the roving-focus order so arrows step over it. It stays announced as aria-disabled="true", explaining why focus never arrives. Not inherited: the node is still rendered, its subtree still expands, and its descendants stay fully navigable and selectable.`},{name:"textValue",type:"string",required:!1,description:"The text typeahead matches this node against, instead of its rendered label, published as data-text-value. Use it when the label is not plain text \u2014 an icon plus a truncated name, a highlighted filter match \u2014 or when the searchable text differs from the visible one. Omitted, the node's own text is used, excluding its aria-hidden indicator and its nested group."},{name:"hasChildren",type:"boolean",required:!1,description:"Declares whether this node is a branch, overriding the nested-group scan. true makes the node report aria-expanded and accept ArrowRight with no group mounted at all, which a lazily-loaded branch needs. false forces the node to read as a leaf even with a group among its children. Inferred from the presence of a nested group when omitted."}]},{name:"Group",description:`One role="group" container for a branch's child items, rendered inside the TreeItem it belongs to. It is unmounted while its branch is collapsed rather than hidden, which is what makes the roving tabindex span currently-visible items for free. Publishes data-state expanded/collapsed, the hook a force-mounted group is styled by while its branch is closed.`,props:[{name:"forceMount",type:"boolean",defaultValue:"false",required:!1,description:`Keeps the group mounted while its branch is collapsed, for exit animations. The skin then hides it on data-state="collapsed", since painting it would contradict the branch's aria-expanded="false"; override that rule to animate the exit. A force-mounted group's items stay registered, counting towards their parent's tri-state.`}]},{name:"ItemIndicator",description:"A branch's expand/collapse affordance, rendered inside the TreeItem it belongs to. It mirrors its item's data-state (expanded/collapsed) so the skin can rotate one glyph rather than swap two, and clicking it toggles the branch without selecting the row. Decorative to assistive technology: the item's own aria-expanded already carries the state. A collection tree derives one for every branch, so a hand-composed tree and a collection tree have the same affordance.",props:[],slots:[{name:"default",description:"A TreeItem's expand/collapse affordance (e.g. a chevron)."}]}],slots:[{name:"default",description:"Root content \u2014 TreeItems. Ignored while `collection` is supplied, which is then the source of truth."},{name:"render-label",frameworks:["svelte"],exception:"render-prop",frameworksReason:"svelte expose render-label as native content projection for the renderLabel rendering capability. Other frameworks pass the documented renderLabel render prop or template instead of a named slot with this spelling.",description:"Renders a collection node's content \u2014 label and any indicator. Ignored without collection, since composition already puts the consumer in charge. Defaults to the node's label, falling back to its nodeId. In Angular this is `labelTemplate`, a TemplateRef taking the same context."}],states:["expanded","collapsed","selected","unselected","loading","indeterminate"],controlledUncontrolled:"Expansion and selection each support both controlled and uncontrolled usage, independently of one another.",formBehavior:"Not applicable \u2014 Tree does not participate in forms. Angular alone additionally registers as a ControlValueAccessor, which is an extension of that framework rather than a capability the other four owe; see frameworkExtensions.",validationBehavior:"Not applicable \u2014 Tree carries no value and participates in no validation.",accessibility:{role:"tree (root), treeitem (TreeItem), group (TreeGroup)",keyboard:[{key:"ArrowUp/ArrowDown",behavior:"Moves focus between currently-visible items, no wrap."},{key:"Home/End",behavior:"Moves focus to the first/last currently-visible item."},{key:"ArrowRight",behavior:"Expands a collapsed branch, or moves focus to its first child if already expanded. A node declared a branch through the item's hasChildren counts as one with nothing rendered under it yet, which is what lets ArrowRight trigger loadChildren."},{key:"ArrowLeft",behavior:"Collapses an expanded node with children, or moves focus to its parent."},{key:"Printable characters",behavior:"Typeahead: moves focus to the next currently-visible node whose label starts with what was typed, wrapping around. A 1s buffer accumulates characters into one search; repeating a single letter cycles through the nodes starting with it. A node's label is its `data-text-value` when it has one, otherwise its own text \u2014 excluding its aria-hidden TreeItemIndicator and any nested TreeGroup, so a chevron glyph and a child's text never enter the match. Typeahead moves focus only, it never selects; Space is claimed by selection, so it never starts a search."},{key:"*",behavior:"Expands every collapsed sibling of the focused node \u2014 the nodes at the same level under the same parent. Focus does not move."},{key:"Shift+ArrowUp/Shift+ArrowDown",behavior:`selectionMode="multiple" only: moves focus to the previous/next visible node and toggles that node's selection, extending the selection as focus travels. Plain ArrowUp/ArrowDown elsewhere.`},{key:"Shift+Space",behavior:'selectionMode="multiple" only: selects the contiguous run of visible nodes between the most recently *selected* node and the focused one, inclusive, in one update. The anchor is the last node selected, not the last node focused, so walking with plain arrows and then pressing Shift+Space extends from wherever the selection last landed \u2014 which is the point of the binding. With no anchor yet (or one that has since been collapsed away) it selects the focused node alone, exactly as Space would.'},{key:"Ctrl+ArrowUp/Ctrl+ArrowDown",behavior:"Identical to plain ArrowUp/ArrowDown: moves focus to the previous/next visible node without touching the selection. There is no separate handler, and none is needed \u2014 selection never follows focus in this tree, so the plain arrows already do what the modifier asks for. It is listed because a user arriving from APG's alternative multi-select model, where the plain arrows *do* move the selection, will reach for it; and because a Control-modified arrow must not start a typeahead search, which is the one thing that would otherwise differ."},{key:"Control+Shift+Home/Control+Shift+End",behavior:`selectionMode="multiple" only: moves focus to the first/last visible node and selects every node from the previously focused one through it. This is APG's binding. The bare Shift+Home/Shift+End form is kept as an alias for one release \u2014 it is what the component shipped with \u2014 but is not the documented one. Plain Home/End moves focus only.`},{key:"Ctrl+A",behavior:'selectionMode="multiple" only: selects every currently-visible node, or clears the selection when every one of them is already selected. Focus does not move. The toggle matters because the same chord is the only affordance a user has for undoing it. The scope is the *rendered* tree rather than the whole tree, which is as far as it can reach: a collapsed branch is unmounted, and the root holds no list of what is inside one.'},{key:"Enter",behavior:'Selects the focused node *and* fires the activate event. APG: "Activates a node, i.e., performs its default action."'},{key:"Space",behavior:'Selects the focused node and nothing else \u2014 never fires activate. APG: "Toggles the selection state of the focused node."'}],ariaAttributes:['aria-label or aria-labelledby on the root, supplied by the consumer \u2014 normative for role="tree" (see `namingRequirement`)','aria-multiselectable on the root when selectionMode is "multiple"',"each item's aria-level reflects its nesting depth","aria-setsize and aria-posinset (1-based) on every item, counting its siblings at the same level under the same parent \u2014 required rather than optional here because collapsed subtrees are unmounted, so assistive tech cannot infer a set it cannot see","author-supplied aria-level, aria-posinset and aria-setsize override the computed ones. This is contracted, not incidental: it is what the virtualization pattern depends on \u2014 a windowed tree renders a slice of the nodes and has to state the real positions itself \u2014 and it is exactly the case APG requires the attributes for. Every framework spreads consumer attributes after its own, and a Tree item given an explicit aria-posinset must render that value",`the computed pair is measured from the rendered DOM after mount, so server-rendered HTML carries neither. A non-hydrated tree \u2014 an Astro island, an RSC subtree \u2014 must supply them itself through the override above, which is the same instruction the virtualization pattern already gives. There is no equivalent of the roving tab stop's "every item is a tab stop until the effect runs" fallback here: a guessed position is a wrong position, and a wrong "3 of 7" is worse than none`,'aria-selected reflects selection unless selectionMode is "none" \u2014 or selectionPropagation is "descendants", where aria-checked carries the state instead and aria-selected is omitted entirely',"aria-expanded is set only on branch items \u2014 those with a nested TreeGroup, plus those declared as branches through the item's hasChildren, which is how a lazy branch announces itself before its children exist",'aria-busy="true" on an item whose loadChildren call is still pending','aria-checked (true/false/"mixed") on every item when selectionPropagation is "descendants" \u2014 never alongside aria-selected: APG allows either, and on a parent whose children are partly selected the two contradict each other ("false" and "mixed" at once)'],namingRequirement:`The root must carry an accessible name via aria-label or aria-labelledby, supplied by the consumer. This is normative rather than advisory \u2014 APG: "The element with role tree has either a visible label referenced by aria-labelledby or a value specified for aria-label." No prop is needed, because passthrough already carries both attributes in all five packages; and nothing inside the Tree can supply it, since role="tree" is name-from-author only and the node labels inside it name the tree no more than a list's items name the list. An unnamed tree announces as a bare "tree", which is indistinguishable from every other tree on the page.`,focusManagement:'Single tab stop with roving tabindex over currently-visible items only \u2014 collapsed subtrees are unmounted, not merely hidden, so they are naturally excluded (under disabledBehavior="selection" the disabled ones stay in). The stop is seeded from the first rendered id present in selectedIds, falling back to the first rendered id \u2014 APG: "If a node is selected before the tree receives focus, focus is set on the selected node", and for a multi-select tree "focus is set on the first selected node". It is re-seeded by the same rule whenever the item holding it is removed, so collapsing or unmounting the focused branch cannot leave the tree with no tabbable item. Only the innermost treeitem under the pointer acts on a click: items nest, so a click on a leaf also reaches every ancestor handler, which would otherwise select and collapse the whole branch above it.'},styling:{cssParts:["root","item","group","item-indicator"],dataAttributes:[...e,"data-state","data-disabled","data-loading","data-checked","data-text-value","data-skdx-tree-node-id","data-skdx-tree-parent-id"],cssCustomProperties:["--skdx-tree-node-depth"]},publicMethods:[{name:"invalidate",signature:"(nodeId?: string): void",description:"Clears the loaded marker on a node so the next expansion fetches again. With nodeId, clears that node and every child it has ever rendered; omitted, clears the whole tree. The consumer owns fetching and caching."}],frameworkExtensions:[{framework:"angular",name:"ControlValueAccessor",type:"ControlValueAccessor",description:"Registers the tree as a Reactive Forms control so [(ngModel)] and formControlName carry the selection. It adds one behaviour no other package has: setDisabledState() disables the whole tree, emitting aria-disabled and data-disabled on the root and refusing selection changes, select-many and select-all. Angular-only because Reactive Forms exists nowhere else \u2014 the other four reach the same place through the controlled `selectedIds` prop and its change event, which Tree already declares."},{framework:"angular",name:"labelTemplate",type:"TemplateRef<SkdxTreeLabelContext>",description:"Template rendering a collection node's content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax.",kind:"prop"},{framework:"angular",name:"labelTemplate",type:"TemplateRef<SkdxTreeLabelContext>",description:"Template rendering a collection node's content. This wrapper receives projected content as a render prop, Snippet or TemplateRef. Other wrappers supply the matching named slot or default content of the composed part; the property is framework rendering syntax."}]};export{a as treeContract};
|
|
@@ -156,6 +156,8 @@ export interface ContextApiContract {
|
|
|
156
156
|
}
|
|
157
157
|
/** One member one framework ships that adapts an ecosystem the other four do not have, not an undeclared gap. */
|
|
158
158
|
export interface FrameworkExtensionContract {
|
|
159
|
+
/** Concrete public member category, checked for presence. Omit only for legacy ecosystem-level integrations. */
|
|
160
|
+
kind?: 'prop' | 'method' | 'slot' | 'event';
|
|
159
161
|
/** Which framework ships it; the keys are {@link ContextApiAccessors}'s. */
|
|
160
162
|
framework: keyof ContextApiAccessors;
|
|
161
163
|
/** Part the member lives on, framework-neutral, or omitted for the component root. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{changeDetail as e}from"./change-reason.js";import{
|
|
1
|
+
import{changeDetail as e}from"./change-reason.js";import{closeAutoFocusEvent as t,dismissalEvents as a,openChangeCompleteEvent as r}from"./overlay-parts.js";import{ROOT_DATA_ATTRIBUTES as n}from"./styling-hooks.js";var l={name:"WorkspaceSwitcher",purpose:"Switches the active context \u2014 workspace, organisation, team, account or project \u2014 from a searchable list with groups, disabled entries, loading and empty states, and a footer for create or manage actions. Composes the Popover parts (PopoverRoot, PopoverTrigger, PopoverPortal, PopoverContent) around the Command parts (Command, CommandInput, CommandList, CommandEmpty, CommandLoading, CommandGroup, CommandItem); the leading glyph is a consumer-supplied node such as an Avatar. Terminology is the consumer's, and the block performs no routing and no persistence. Ships in the blocks package of each framework, not the core package.",props:[{name:"items",type:"ReadonlyArray<{ id: string; label: string; description?: string; group?: string; disabled?: boolean }>",required:!0,description:"Every context the user may switch to, rendered in the order given; items sharing a group are listed under that heading, ungrouped ones first."},{name:"value",type:"string",required:!1,description:"Id of the active context, for controlled usage; pair it with the value-change event."},{name:"defaultValue",type:"string",defaultValue:"''",required:!1,description:"Id of the context active on first render, for uncontrolled usage; the trigger shows the placeholder until one is picked."},{name:"placeholder",type:"string",defaultValue:"'Select'",required:!1,description:"Trigger text shown while no item in the list is the active one."},{name:"label",type:"string",required:!1,description:"Accessible name for the trigger and the result list, for when the visible trigger text is not enough on its own."},{name:"searchLabel",type:"string",defaultValue:"'Search'",required:!1,description:"Accessible name of the search field inside the open panel."},{name:"searchPlaceholder",type:"string",required:!1,description:"Placeholder text shown inside the empty search field; the field renders none when omitted."},{name:"emptyMessage",type:"string",defaultValue:"'No results'",required:!1,description:"Message shown beside the list when the search matches nothing."},{name:"loadingMessage",type:"string",defaultValue:"'Loading'",required:!1,description:"Message announced through a live region while the results are still in flight."},{name:"loading",type:"boolean",defaultValue:"false",required:!1,description:"Marks the results as in flight, showing the loading message and withholding the empty one."},{name:"selectedLabel",type:"string",defaultValue:"'Current'",required:!1,description:"Visually hidden text appended to the active item, naming it for screen reader users."},{name:"leading",type:"Snippet<[WorkspaceSwitcherItem]>",required:!1,frameworks:["svelte"],exception:"render-prop",frameworksReason:"Svelte spells a per-item render hook as a snippet prop, which is both a prop and a slot in that framework's own idiom; the other frameworks take it through renderLeading or the `leading` scoped slot.",description:"The Svelte snippet form of `renderLeading`, rendered once per item with that item as its argument."},{name:"renderLeading",type:"unknown",required:!1,frameworks:["react","angular","webComponents"],exception:"render-prop",frameworksReason:"Vue takes this as a scoped slot and Svelte as a snippet of the same name rather than a prop, because a per-item render hook is a slot with slot props in their own idioms; React, Angular and Web Components take the function, since one markup slot cannot render once per item.",description:"Renders a decorative glyph, such as an avatar or a logo, for one item and for the trigger. No leading region renders when omitted. A prop in React and Angular; Vue uses the `leading` scoped slot and Svelte the `leading` snippet; Web Components set the function as a property."},{name:"actions",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot rather than a prop \u2014 Vue because a renderable region is a slot in Vue's own idiom, Web Components because a custom element attribute carries a string and cannot carry a node. Both slot spellings are declared under `slots`.",description:"Controls placed in the panel's footer, such as create and manage buttons. No footer region renders when omitted. A prop in React, Svelte, and Angular; Vue and Web Components use the `actions` slot."},{name:"trigger",type:"unknown",required:!1,frameworks:["react","svelte","angular"],exception:"render-prop",frameworksReason:"Vue and Web Components take this as a named slot rather than a prop \u2014 Vue because a renderable region is a slot in Vue's own idiom, Web Components because a custom element attribute carries a string and cannot carry a node. Both slot spellings are declared under `slots`.",description:"Replaces the derived trigger button with the consumer's own element, which still receives the popover wiring. A prop in React, Svelte, and Angular; Vue and Web Components use the `trigger` slot."},{name:"open",type:"boolean",required:!1,description:"Whether the panel is open, for controlled usage; pair it with the open-change event."},{name:"defaultOpen",type:"boolean",defaultValue:"false",required:!1,description:"Whether the panel is open on first render, for uncontrolled usage."}],events:[...a("panel"),t("panel"),r("panel"),{name:"value-change",detail:e("string"),description:"Fires with the id of the item the user picked, immediately before the panel closes."},{name:"open-change",detail:"boolean",description:"Fires with the new open state whenever the panel opens or closes, controlled or not."}],slots:[{name:"trigger",description:"The trigger prop's element, replacing the derived trigger button entirely."},{name:"leading",frameworks:["vue","svelte"],exception:"render-prop",frameworksReason:"Vue spells a per-item render hook as a scoped slot and Svelte as a snippet; React, Angular and Web Components take the equivalent function through the prop of the same purpose.",description:"The renderLeading prop's glyph, scoped to the item it decorates and to the trigger."},{name:"actions",description:"The actions prop's content \u2014 the footer's create and manage controls."}],states:["default"],controlledUncontrolled:"Both the active id and the open state are controlled when their prop is set and tracked internally otherwise; each reports every change through its event either way.",formBehavior:"Not applicable \u2014 WorkspaceSwitcher submits nothing and participates in no form.",validationBehavior:"Not applicable \u2014 the active id is always one of the items and carries no validation.",accessibility:{role:'button (derived trigger with aria-haspopup="dialog" and aria-expanded from the core PopoverTrigger; the popup is a non-modal Popover holding a Command listbox with a search input, so Tab and outside interaction leave it without an Escape key)',keyboard:[{key:"ArrowDown/ArrowUp",behavior:"Moves the highlight between the listed items."},{key:"Enter",behavior:"Selects the highlighted item and closes the panel."},{key:"Escape",behavior:"Closes the panel and returns focus to the trigger."},{key:"Character keys",behavior:"Type into the search field to filter the list down to matching items."}],ariaAttributes:['aria-haspopup="dialog" and aria-expanded on the trigger come from the core PopoverTrigger','the panel is a role="dialog" whose search input owns real focus and points aria-activedescendant at the highlighted option',"the result listbox is named by the label prop, falling back to the placeholder","the leading glyph regions are aria-hidden, so the item label alone carries the meaning","the active item ends with visually hidden text naming it as the current context"],focusManagement:"Opening moves focus into the panel and onto the search field, which keeps it while the arrow keys move a virtual highlight; closing returns focus to the trigger."},styling:{cssParts:["workspace-switcher","leading","current","description","content","search","list","loading","empty","group","item","item-leading","item-label","item-description","footer"],dataAttributes:[...n,"data-selected",{name:"data-skdx-workspace-switcher-generated",frameworks:["webComponents"],exception:"wc-marker",frameworksReason:'Marks a node the element generated for itself rather than one the consumer authored. React, Vue, Svelte and Angular re-render their derived anatomy declaratively, so "mine or theirs" is answered by the framework and no marker is needed.'}],cssCustomProperties:[]},publicMethods:[]};export{l as workspaceSwitcherContract};
|
|
@@ -158,6 +158,8 @@ export declare function validateFields(scope: ParentNode): Promise<boolean>;
|
|
|
158
158
|
export declare function resetFields(scope: ParentNode): void;
|
|
159
159
|
/** Sends focus to a failing field, or to the first control inside a group. */
|
|
160
160
|
export declare function focusFieldTarget(id: string, doc?: Document): void;
|
|
161
|
+
/** Sends focus to the control an `invalid` event fired at — the visible control, when the failing one is a composite's hidden mirror input — and scrolls it into view. */
|
|
162
|
+
export declare function focusInvalidControl(control: HTMLElement): void;
|
|
161
163
|
/** Owns one Field's state machine, connected to its root element and re-synced on every render. */
|
|
162
164
|
export declare class FieldController {
|
|
163
165
|
private readonly options;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var C="validity-change",a="data-skdx-field",u="data-skdx-field-name",p="data-skdx-field-message",F="data-skdx-field-description",x="data-skdx-field-error",$="data-skdx-field-character-count",E="data-skdx-field-pending",c="data-skdx-field-resubmit",f="data-skdx-form-field",_="data-skdx-form-message",G=["validity-change","invalid","change","blur"],D="data-skdx-error-summary",j=1e3;function M(i){let e=Math.abs(i),t=e===1?"character":"characters";return i<0?`You have ${e} ${t} too many`:`You have ${e} ${t} remaining`}function V(i,e,t=0){return t<=0?!0:i>=e*t/100}function Y(i){return i.map((e,t)=>t===i.length-1||/[.!?]$/.test(e)?e:`${e}.`).join(" ")}var O="This field is invalid.",w="data-skdx-field-control",I=[`[${w}]`,'input:not([type="hidden"])',"select","textarea",'[role="textbox"]','[role="searchbox"]','[role="combobox"]','[role="listbox"]','[role="radiogroup"]','[role="group"]','[role="slider"]','[role="spinbutton"]','[role="checkbox"]','[role="radio"]','[role="switch"]'].join(", "),z="data-skdx-field-required-indicator",k=new Set(["INPUT","SELECT","TEXTAREA"]),R=new Set(["radiogroup","group"]),B=['input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","button:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(", ");function T(i){return i==null?[]:(Array.isArray(i)?i:[i]).filter(t=>typeof t=="string"&&t.trim()!=="")}function S(i){for(let e of Array.from(i.querySelectorAll(I)))if(e.getAttribute("aria-hidden")!=="true"&&e.closest(`[${a}]`)===i)return e;return null}function m(i,e){return v(i,a,e)}function v(i,e,t){for(let r of Array.from(i.querySelectorAll(t)))if(r.closest(`[${e}]`)===i)return r;return null}function P(i){if(!i)return;let e=i;return e.type==="checkbox"||e.type==="radio"?e.checked:"value"in i?e.value:i.querySelector('input[aria-hidden="true"]')?.value}function d(i){return i==null||i===!1||i===""?!1:!(Array.isArray(i)&&i.length===0)}function o(i,e,t){t?i.setAttribute(e,""):i.removeAttribute(e)}function y(i,...e){let t=i.split(/\s+/).filter(Boolean);for(let r of e)r&&!t.includes(r)&&t.push(r);return t.join(" ")}function K(i){return i.closest("form, skdx-form")??i.parentElement??i}function N(i){let e=S(i),r=m(i,`[${x}]`)?.textContent?.trim()||i.getAttribute(p)||i.getAttribute(u)||"";return!e?.id||!r?[]:[{id:e.id,message:r}]}function H(i){let e=v(i,f,I);if(!e?.id||e.getAttribute("aria-invalid")!=="true")return[];let r=v(i,f,`[${_}]:not([hidden])`)?.textContent?.trim()||i.getAttribute(u)||"";return r?[{id:e.id,message:r}]:[]}function Q(i){return Array.from(i.querySelectorAll(`[${a}][data-invalid], [${f}]`)).flatMap(t=>(t.hasAttribute(a)?N:H)(t))}var b="__skdxFieldCheckValidity",g="__skdxFieldReset";async function X(i){let e=Array.from(i.querySelectorAll(`[${a}]`));return(await Promise.all(e.map(r=>r[b]?.()??Promise.resolve(!0)))).every(Boolean)}function J(i){for(let e of Array.from(i.querySelectorAll(`[${a}]`)))e[g]?.()}function W(i,e=document){let t=e.getElementById(i);if(!t)return;let r=t.getAttribute("role"),s=(t.tagName==="FIELDSET"||r!==null&&R.has(r)?t.querySelector(B):null)??t;s.focus(),s.scrollIntoView?.({block:"center"})}var A=class{constructor(e){this.options=e;this.props={};this.root=null;this.form=null;this.control=null;this.baseDescribedBy="";this.baseLabelledBy="";this.wroteLabelledBy=!1;this.wroteRequired=!1;this.wroteDisabled=!1;this.wroteGroupDisabled=!1;this.runToken=0;this.pending=!1;this.injected=[];this.custom=[];this.characterCount=null;this.awaitingSubmit=!1;this.handleInput=()=>{let e=this.isOverLimit(this.snapshot.count),t=this.readCount();this.update({dirty:!0,filled:d(this.resolveValue()),count:t,errors:this.composeErrors(t)}),this.scheduleCountAnnouncement(t,e),(this.props.mode==="change"||this.snapshot.errors.length>0)&&this.scheduleValidation()};this.handleFocusOut=()=>{let e=this.readCount();this.update({touched:!0,filled:d(this.resolveValue()),count:e,errors:this.composeErrors(e)});let t=this.validationTimer!==void 0;clearTimeout(this.validationTimer),this.validationTimer=void 0;let r=this.props.mode??"blur";(t||r==="blur"||this.snapshot.errors.length>0)&&this.runValidation()};this.handleSubmit=e=>{if(!this.form)return;let t=e.target;if(t!==this.form&&t?.closest?.("form")!==this.form||this.isEngineResubmit(e))return;this.markTouched();let r=this.runValidation({silent:this.hasErrorSummary()});if(L(r)){e.preventDefault(),this.awaitingSubmit=!0,Promise.resolve(r).then(()=>{this.awaitingSubmit&&(this.awaitingSubmit=!1,this.resubmitIfSettled())});return}(r.length>0||this.pending)&&e.preventDefault()};this.snapshot={controlId:"",errors:[],valid:!0,touched:!1,dirty:!1,filled:!1,count:0,validity:null}}get state(){return this.snapshot}setProps(e){let t=this.props.value;this.props=e;let r=T(e.errors??null),n=!q(this.injected,r);n&&(this.injected=r);let s=e.value!==t;if(!n&&!s)return;let l=this.readCount();this.update({count:l,filled:d(this.resolveValue()),errors:this.composeErrors(l)})}setCharacterCount(e){if((this.characterCount?.maxLength??null)===(e?.maxLength??null)&&(this.characterCount?.threshold??0)===(e?.threshold??0))return;this.characterCount=e;let r=this.readCount();this.update({count:r,errors:this.composeErrors(r)})}readCount(){let e=this.resolveValue();return typeof e=="string"?e.length:0}countMessage(e){return(this.props.getCharacterCountMessage??M)(e)}isOverLimit(e){return this.characterCount!==null&&e>this.characterCount.maxLength}composeErrors(e=this.snapshot.count){let t=[...this.injected,...this.custom];return this.characterCount&&this.isOverLimit(e)&&t.push(this.countMessage(this.characterCount.maxLength-e)),t}scheduleCountAnnouncement(e,t){let r=this.characterCount;if(!r)return;if(clearTimeout(this.announceTimer),this.isOverLimit(e)){t||this.options.announce(this.countMessage(r.maxLength-e),"assertive");return}if(!V(e,r.maxLength,r.threshold))return;let n=r.maxLength-e;this.announceTimer=setTimeout(()=>{this.options.announce(this.countMessage(n),"polite")},1e3)}connect(e){this.root=e,e.setAttribute(a,""),Object.defineProperty(e,b,{value:()=>this.validate(),configurable:!0,enumerable:!1,writable:!0}),Object.defineProperty(e,g,{value:()=>this.reset(),configurable:!0,enumerable:!1,writable:!0}),e.addEventListener("input",this.handleInput,!0),e.addEventListener("change",this.handleInput,!0),e.addEventListener("focusout",this.handleFocusOut,!0),this.form=e.closest("form"),this.form&&e.ownerDocument.addEventListener("submit",this.handleSubmit,!0),this.sync();let t=this.readCount();this.update({filled:d(this.resolveValue()),count:t,errors:this.composeErrors(t)})}disconnect(){clearTimeout(this.announceTimer),clearTimeout(this.validationTimer),this.validationTimer=void 0,this.awaitingSubmit=!1;let e=this.root;e&&(e.removeEventListener("input",this.handleInput,!0),e.removeEventListener("change",this.handleInput,!0),e.removeEventListener("focusout",this.handleFocusOut,!0),this.form&&e.ownerDocument.removeEventListener("submit",this.handleSubmit,!0),delete e[b],delete e[g],this.root=null,this.form=null,this.control=null)}sync(){let e=this.root;if(!e)return;let t=S(e);t!==this.control&&(this.control=t,this.baseDescribedBy=t?.getAttribute("aria-describedby")??"",this.baseLabelledBy=t?.getAttribute("aria-labelledby")??"",this.wroteLabelledBy=!1,this.wroteRequired=!1,this.wroteDisabled=!1,this.wroteGroupDisabled=!1);let{name:r}=this.props;r?e.setAttribute(u,r):e.removeAttribute(u);let n=this.snapshot.errors.join(" ");n?e.setAttribute(p,n):e.removeAttribute(p),this.applyStateAttributes(e),t&&(t.id||(t.id=this.options.controlId),t.id!==this.snapshot.controlId&&(this.snapshot={...this.snapshot,controlId:t.id,validity:this.readValidity()},this.options.onSnapshotChange(this.snapshot)),this.applyDescribedBy(e,t),this.snapshot.errors.length>0?t.setAttribute("aria-invalid","true"):t.removeAttribute("aria-invalid"),this.applyLabelledBy(e,t),this.applyConstraintState(t),this.applyStateAttributes(t))}applyDescribedBy(e,t){let r=m(e,`[${F}]`)!==null,n=m(e,`[${x}]`)!==null,s=y(this.baseDescribedBy,r?this.options.descriptionId:void 0,n?this.options.errorId:void 0);s?t.setAttribute("aria-describedby",s):t.removeAttribute("aria-describedby")}applyLabelledBy(e,t){let r=e.ownerDocument.getElementById(this.options.labelId)!==null;this.options.grouped&&r?(t.setAttribute("aria-labelledby",y(this.baseLabelledBy,this.options.labelId)),this.wroteLabelledBy=!0):this.wroteLabelledBy&&(this.baseLabelledBy?t.setAttribute("aria-labelledby",this.baseLabelledBy):t.removeAttribute("aria-labelledby"),this.wroteLabelledBy=!1)}applyConstraintState(e){let t=k.has(e.tagName),r=this.props.required===!0,n=this.props.disabled===!0;r?(t?e.setAttribute("required",""):e.setAttribute("aria-required","true"),this.wroteRequired=!0):this.wroteRequired&&(e.removeAttribute(t?"required":"aria-required"),this.wroteRequired=!1),n?(t?e.setAttribute("disabled",""):e.setAttribute("aria-disabled","true"),this.wroteDisabled=!0):this.wroteDisabled&&(e.removeAttribute(t?"disabled":"aria-disabled"),this.wroteDisabled=!1),t||this.applyGroupDisabled(e,n)}applyGroupDisabled(e,t){let r=e.getAttribute("role");if(!(!(e.tagName==="FIELDSET"||r!==null&&R.has(r))||!t&&!this.wroteGroupDisabled)){for(let s of e.querySelectorAll("input, select, textarea, button"))t?s.setAttribute("disabled",""):s.removeAttribute("disabled");this.wroteGroupDisabled=t}}validate(){return Promise.resolve(this.runValidation()).then(e=>e.length===0)}reset(){this.injected=[],this.custom=[],this.pending=!1,this.awaitingSubmit=!1,this.runToken++,clearTimeout(this.announceTimer),clearTimeout(this.validationTimer),this.validationTimer=void 0,this.markPending(!1);let e=this.readCount();this.update({touched:!1,dirty:!1,count:e,filled:d(this.resolveValue()),errors:this.composeErrors(e)}),this.sync()}markTouched(){this.snapshot.touched||this.update({touched:!0})}applyStateAttributes(e){let{errors:t,touched:r,dirty:n,filled:s,count:l}=this.snapshot;o(e,"data-invalid",t.length>0),o(e,"data-valid",t.length===0),o(e,"data-touched",r),o(e,"data-dirty",n),o(e,"data-filled",s),o(e,"data-over-limit",this.isOverLimit(l)),o(e,"data-disabled",this.props.disabled===!0)}resolveValue(){return this.props.value!==void 0?this.props.value:P(this.control)}readValidity(){return this.control?.validity??null}markPending(e){this.root&&o(this.root,E,e)}nativeMessage(){let e=this.control;return!e?.validity||e.validity.valid?null:e.validationMessage||this.props.invalidMessage||O}runValidation(e={}){let t=++this.runToken,r=this.props.validate?.(this.resolveValue());return L(r)?(this.pending=!0,this.markPending(!0),Promise.resolve(r).then(n=>t!==this.runToken?this.snapshot.errors:(this.pending=!1,this.markPending(!1),this.commit(n,e)))):this.commit(r,e)}commit(e,t){if(this.custom=T(e),this.custom.length===0){let h=this.nativeMessage();h&&!this.injected.includes(h)&&(this.custom=[h])}let r=this.readCount(),n=this.composeErrors(r),s=this.snapshot.errors.length===0;this.update({errors:n,count:r,filled:d(this.resolveValue())});let l=n[0];return l&&s&&!t.silent&&this.options.announce(l,"assertive"),n}update(e){let t={...this.snapshot,...e,valid:!0,validity:this.readValidity()};t.valid=t.errors.length===0,!U(this.snapshot,t)&&(this.snapshot=t,this.sync(),this.options.onSnapshotChange(t),this.root?.dispatchEvent(new CustomEvent(C,{bubbles:!0,composed:!0,detail:{valid:t.valid,errors:t.errors,touched:t.touched,dirty:t.dirty,filled:t.filled,count:t.count,validity:t.validity}})))}scheduleValidation(){clearTimeout(this.validationTimer),this.validationTimer=void 0;let e=this.props.mode==="change"?this.props.validationDebounceTime??0:0;if(e<=0){this.runValidation();return}this.validationTimer=setTimeout(()=>{this.validationTimer=void 0,this.runValidation()},e)}hasErrorSummary(){return this.form?.querySelector(`[${D}]`)!=null}isEngineResubmit(e){return this.form?.hasAttribute(c)?(this.snapshot.errors.length>0&&e.preventDefault(),!0):!1}resubmitIfSettled(){let e=this.form;if(!(!e||typeof e.requestSubmit!="function")&&!e.querySelector(`[${E}]`)&&!e.querySelector(`[${a}][data-invalid]`)){e.setAttribute(c,"");try{e.requestSubmit()}finally{e.removeAttribute(c)}}}};function L(i){return typeof i?.then=="function"}function q(i,e){return i.length===e.length&&i.every((t,r)=>t===e[r])}function U(i,e){return i.controlId===e.controlId&&i.valid===e.valid&&i.touched===e.touched&&i.dirty===e.dirty&&i.filled===e.filled&&i.count===e.count&&i.validity===e.validity&&i.errors.length===e.errors.length&&i.errors.every((t,r)=>t===e.errors[r])}export{j as CHARACTER_COUNT_ANNOUNCE_DELAY_MS,G as ERROR_SUMMARY_RESCAN_EVENTS,$ as FIELD_CHARACTER_COUNT_ATTRIBUTE,w as FIELD_CONTROL_ATTRIBUTE,I as FIELD_CONTROL_SELECTOR,F as FIELD_DESCRIPTION_ATTRIBUTE,x as FIELD_ERROR_ATTRIBUTE,D as FIELD_ERROR_SUMMARY_ATTRIBUTE,p as FIELD_MESSAGE_ATTRIBUTE,u as FIELD_NAME_ATTRIBUTE,E as FIELD_PENDING_ATTRIBUTE,z as FIELD_REQUIRED_INDICATOR_ATTRIBUTE,c as FIELD_RESUBMIT_ATTRIBUTE,a as FIELD_ROOT_ATTRIBUTE,C as FIELD_VALIDITY_CHANGE_EVENT,f as FORM_FIELD_ATTRIBUTE,_ as FORM_MESSAGE_ATTRIBUTE,A as FieldController,O as NATIVE_INVALID_FALLBACK_MESSAGE,M as characterCountMessage,V as characterCountVisible,Q as collectFieldErrors,K as errorSummaryScope,S as findFieldControl,W as focusFieldTarget,d as isFilled,Y as joinFieldMessages,T as normalizeMessages,P as readControlValue,J as resetFields,X as validateFields};
|
|
1
|
+
var F="validity-change",o="data-skdx-field",u="data-skdx-field-name",f="data-skdx-field-message",_="data-skdx-field-description",I="data-skdx-field-error",j="data-skdx-field-character-count",T="data-skdx-field-pending",p="data-skdx-field-resubmit",h="data-skdx-form-field",D="data-skdx-form-message",Y=["validity-change","invalid","change","blur"],M="data-skdx-error-summary",z=1e3;function V(i){let e=Math.abs(i),t=e===1?"character":"characters";return i<0?`You have ${e} ${t} too many`:`You have ${e} ${t} remaining`}function O(i,e,t=0){return t<=0?!0:i>=e*t/100}function K(i){return i.map((e,t)=>t===i.length-1||/[.!?]$/.test(e)?e:`${e}.`).join(" ")}var w="This field is invalid.",k="data-skdx-field-control",g=[`[${k}]`,'input:not([type="hidden"])',"select","textarea",'[role="textbox"]','[role="searchbox"]','[role="combobox"]','[role="listbox"]','[role="radiogroup"]','[role="group"]','[role="slider"]','[role="spinbutton"]','[role="checkbox"]','[role="radio"]','[role="switch"]'].join(", "),Q="data-skdx-field-required-indicator",B=new Set(["INPUT","SELECT","TEXTAREA"]),C=new Set(["radiogroup","group"]),P=['input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])","button:not([disabled])",'[tabindex]:not([tabindex="-1"])'].join(", ");function y(i){return i==null?[]:(Array.isArray(i)?i:[i]).filter(t=>typeof t=="string"&&t.trim()!=="")}function R(i){for(let e of Array.from(i.querySelectorAll(g)))if(e.getAttribute("aria-hidden")!=="true"&&e.closest(`[${o}]`)===i)return e;return null}function m(i,e){return v(i,o,e)}function v(i,e,t){for(let r of Array.from(i.querySelectorAll(t)))if(r.closest(`[${e}]`)===i)return r;return null}function H(i){if(!i)return;let e=i;return e.type==="checkbox"||e.type==="radio"?e.checked:"value"in i?e.value:i.querySelector('input[aria-hidden="true"]')?.value}function d(i){return i==null||i===!1||i===""?!1:!(Array.isArray(i)&&i.length===0)}function a(i,e,t){t?i.setAttribute(e,""):i.removeAttribute(e)}function A(i,...e){let t=i.split(/\s+/).filter(Boolean);for(let r of e)r&&!t.includes(r)&&t.push(r);return t.join(" ")}function X(i){return i.closest("form, skdx-form")??i.parentElement??i}function N(i){let e=R(i),r=m(i,`[${I}]`)?.textContent?.trim()||i.getAttribute(f)||i.getAttribute(u)||"";return!e?.id||!r?[]:[{id:e.id,message:r}]}function q(i){let e=v(i,h,g);if(!e?.id||e.getAttribute("aria-invalid")!=="true")return[];let r=v(i,h,`[${D}]:not([hidden])`)?.textContent?.trim()||i.getAttribute(u)||"";return r?[{id:e.id,message:r}]:[]}function J(i){return Array.from(i.querySelectorAll(`[${o}][data-invalid], [${h}]`)).flatMap(t=>(t.hasAttribute(o)?N:q)(t))}var b="__skdxFieldCheckValidity",E="__skdxFieldReset";async function W(i){let e=Array.from(i.querySelectorAll(`[${o}]`));return(await Promise.all(e.map(r=>r[b]?.()??Promise.resolve(!0)))).every(Boolean)}function Z(i){for(let e of Array.from(i.querySelectorAll(`[${o}]`)))e[E]?.()}function S(i){let e=i.getAttribute("role"),r=(i.tagName==="FIELDSET"||e!==null&&C.has(e)?i.querySelector(P):null)??i;r.focus(),r.scrollIntoView?.({block:"center"})}function ee(i,e=document){let t=e.getElementById(i);t&&S(t)}function U(i){if(i.getAttribute("aria-hidden")!=="true")return i;let e=i.closest(`[${o}], [${h}]`)??i.parentElement;for(let t of Array.from(e?.querySelectorAll(g)??[]))if(t.getAttribute("aria-hidden")!=="true")return t;return i}function te(i){S(U(i))}var L=class{constructor(e){this.options=e;this.props={};this.root=null;this.form=null;this.control=null;this.baseDescribedBy="";this.baseLabelledBy="";this.wroteLabelledBy=!1;this.wroteRequired=!1;this.wroteDisabled=!1;this.wroteGroupDisabled=!1;this.runToken=0;this.pending=!1;this.injected=[];this.custom=[];this.characterCount=null;this.awaitingSubmit=!1;this.handleInput=()=>{let e=this.isOverLimit(this.snapshot.count),t=this.readCount();this.update({dirty:!0,filled:d(this.resolveValue()),count:t,errors:this.composeErrors(t)}),this.scheduleCountAnnouncement(t,e),(this.props.mode==="change"||this.snapshot.errors.length>0)&&this.scheduleValidation()};this.handleFocusOut=()=>{let e=this.readCount();this.update({touched:!0,filled:d(this.resolveValue()),count:e,errors:this.composeErrors(e)});let t=this.validationTimer!==void 0;clearTimeout(this.validationTimer),this.validationTimer=void 0;let r=this.props.mode??"blur";(t||r==="blur"||this.snapshot.errors.length>0)&&this.runValidation()};this.handleSubmit=e=>{if(!this.form)return;let t=e.target;if(t!==this.form&&t?.closest?.("form")!==this.form||this.isEngineResubmit(e))return;this.markTouched();let r=this.runValidation({silent:this.hasErrorSummary()});if(x(r)){e.preventDefault(),this.awaitingSubmit=!0,Promise.resolve(r).then(()=>{this.awaitingSubmit&&(this.awaitingSubmit=!1,this.resubmitIfSettled())});return}(r.length>0||this.pending)&&e.preventDefault()};this.snapshot={controlId:"",errors:[],valid:!0,touched:!1,dirty:!1,filled:!1,count:0,validity:null}}get state(){return this.snapshot}setProps(e){let t=this.props.value;this.props=e;let r=y(e.errors??null),n=!$(this.injected,r);n&&(this.injected=r);let s=e.value!==t;if(!n&&!s)return;let l=this.readCount();this.update({count:l,filled:d(this.resolveValue()),errors:this.composeErrors(l)})}setCharacterCount(e){if((this.characterCount?.maxLength??null)===(e?.maxLength??null)&&(this.characterCount?.threshold??0)===(e?.threshold??0))return;this.characterCount=e;let r=this.readCount();this.update({count:r,errors:this.composeErrors(r)})}readCount(){let e=this.resolveValue();return typeof e=="string"?e.length:0}countMessage(e){return(this.props.getCharacterCountMessage??V)(e)}isOverLimit(e){return this.characterCount!==null&&e>this.characterCount.maxLength}composeErrors(e=this.snapshot.count){let t=[...this.injected,...this.custom];return this.characterCount&&this.isOverLimit(e)&&t.push(this.countMessage(this.characterCount.maxLength-e)),t}scheduleCountAnnouncement(e,t){let r=this.characterCount;if(!r)return;if(clearTimeout(this.announceTimer),this.isOverLimit(e)){t||this.options.announce(this.countMessage(r.maxLength-e),"assertive");return}if(!O(e,r.maxLength,r.threshold))return;let n=r.maxLength-e;this.announceTimer=setTimeout(()=>{this.options.announce(this.countMessage(n),"polite")},1e3)}connect(e){this.root=e,e.setAttribute(o,""),Object.defineProperty(e,b,{value:()=>this.validate(),configurable:!0,enumerable:!1,writable:!0}),Object.defineProperty(e,E,{value:()=>this.reset(),configurable:!0,enumerable:!1,writable:!0}),e.addEventListener("input",this.handleInput,!0),e.addEventListener("change",this.handleInput,!0),e.addEventListener("focusout",this.handleFocusOut,!0),this.form=e.closest("form"),this.form&&e.ownerDocument.addEventListener("submit",this.handleSubmit,!0),this.sync();let t=this.readCount();this.update({filled:d(this.resolveValue()),count:t,errors:this.composeErrors(t)})}disconnect(){clearTimeout(this.announceTimer),clearTimeout(this.validationTimer),this.validationTimer=void 0,this.awaitingSubmit=!1;let e=this.root;e&&(e.removeEventListener("input",this.handleInput,!0),e.removeEventListener("change",this.handleInput,!0),e.removeEventListener("focusout",this.handleFocusOut,!0),this.form&&e.ownerDocument.removeEventListener("submit",this.handleSubmit,!0),delete e[b],delete e[E],this.root=null,this.form=null,this.control=null)}sync(){let e=this.root;if(!e)return;let t=R(e);t!==this.control&&(this.control=t,this.baseDescribedBy=t?.getAttribute("aria-describedby")??"",this.baseLabelledBy=t?.getAttribute("aria-labelledby")??"",this.wroteLabelledBy=!1,this.wroteRequired=!1,this.wroteDisabled=!1,this.wroteGroupDisabled=!1);let{name:r}=this.props;r?e.setAttribute(u,r):e.removeAttribute(u);let n=this.snapshot.errors.join(" ");n?e.setAttribute(f,n):e.removeAttribute(f),this.applyStateAttributes(e),t&&(t.id||(t.id=this.options.controlId),t.id!==this.snapshot.controlId&&(this.snapshot={...this.snapshot,controlId:t.id,validity:this.readValidity()},this.options.onSnapshotChange(this.snapshot)),this.applyDescribedBy(e,t),this.snapshot.errors.length>0?t.setAttribute("aria-invalid","true"):t.removeAttribute("aria-invalid"),this.applyLabelledBy(e,t),this.applyConstraintState(t),this.applyStateAttributes(t))}applyDescribedBy(e,t){let r=m(e,`[${_}]`)!==null,n=m(e,`[${I}]`)!==null,s=A(this.baseDescribedBy,r?this.options.descriptionId:void 0,n?this.options.errorId:void 0);s?t.setAttribute("aria-describedby",s):t.removeAttribute("aria-describedby")}applyLabelledBy(e,t){let r=e.ownerDocument.getElementById(this.options.labelId)!==null;this.options.grouped&&r?(t.setAttribute("aria-labelledby",A(this.baseLabelledBy,this.options.labelId)),this.wroteLabelledBy=!0):this.wroteLabelledBy&&(this.baseLabelledBy?t.setAttribute("aria-labelledby",this.baseLabelledBy):t.removeAttribute("aria-labelledby"),this.wroteLabelledBy=!1)}applyConstraintState(e){let t=B.has(e.tagName),r=this.props.required===!0,n=this.props.disabled===!0;r?(t?e.setAttribute("required",""):e.setAttribute("aria-required","true"),this.wroteRequired=!0):this.wroteRequired&&(e.removeAttribute(t?"required":"aria-required"),this.wroteRequired=!1),n?(t?e.setAttribute("disabled",""):e.setAttribute("aria-disabled","true"),this.wroteDisabled=!0):this.wroteDisabled&&(e.removeAttribute(t?"disabled":"aria-disabled"),this.wroteDisabled=!1),t||this.applyGroupDisabled(e,n)}applyGroupDisabled(e,t){let r=e.getAttribute("role");if(!(!(e.tagName==="FIELDSET"||r!==null&&C.has(r))||!t&&!this.wroteGroupDisabled)){for(let s of e.querySelectorAll("input, select, textarea, button"))t?s.setAttribute("disabled",""):s.removeAttribute("disabled");this.wroteGroupDisabled=t}}validate(){return Promise.resolve(this.runValidation()).then(e=>e.length===0)}reset(){this.injected=[],this.custom=[],this.pending=!1,this.awaitingSubmit=!1,this.runToken++,clearTimeout(this.announceTimer),clearTimeout(this.validationTimer),this.validationTimer=void 0,this.markPending(!1);let e=this.readCount();this.update({touched:!1,dirty:!1,count:e,filled:d(this.resolveValue()),errors:this.composeErrors(e)}),this.sync()}markTouched(){this.snapshot.touched||this.update({touched:!0})}applyStateAttributes(e){let{errors:t,touched:r,dirty:n,filled:s,count:l}=this.snapshot;a(e,"data-invalid",t.length>0),a(e,"data-valid",t.length===0),a(e,"data-touched",r),a(e,"data-dirty",n),a(e,"data-filled",s),a(e,"data-over-limit",this.isOverLimit(l)),a(e,"data-disabled",this.props.disabled===!0)}resolveValue(){return this.props.value!==void 0?this.props.value:H(this.control)}readValidity(){return this.control?.validity??null}markPending(e){this.root&&a(this.root,T,e)}nativeMessage(){let e=this.control;return!e?.validity||e.validity.valid?null:e.validationMessage||this.props.invalidMessage||w}runValidation(e={}){let t=++this.runToken,r=this.props.validate?.(this.resolveValue());return x(r)?(this.pending=!0,this.markPending(!0),Promise.resolve(r).then(n=>t!==this.runToken?this.snapshot.errors:(this.pending=!1,this.markPending(!1),this.commit(n,e)))):this.commit(r,e)}commit(e,t){if(this.custom=y(e),this.custom.length===0){let c=this.nativeMessage();c&&!this.injected.includes(c)&&(this.custom=[c])}let r=this.readCount(),n=this.composeErrors(r),s=this.snapshot.errors.length===0;this.update({errors:n,count:r,filled:d(this.resolveValue())});let l=n[0];return l&&s&&!t.silent&&this.options.announce(l,"assertive"),n}update(e){let t={...this.snapshot,...e,valid:!0,validity:this.readValidity()};t.valid=t.errors.length===0,!G(this.snapshot,t)&&(this.snapshot=t,this.sync(),this.options.onSnapshotChange(t),this.root?.dispatchEvent(new CustomEvent(F,{bubbles:!0,composed:!0,detail:{valid:t.valid,errors:t.errors,touched:t.touched,dirty:t.dirty,filled:t.filled,count:t.count,validity:t.validity}})))}scheduleValidation(){clearTimeout(this.validationTimer),this.validationTimer=void 0;let e=this.props.mode==="change"?this.props.validationDebounceTime??0:0;if(e<=0){this.runValidation();return}this.validationTimer=setTimeout(()=>{this.validationTimer=void 0,this.runValidation()},e)}hasErrorSummary(){return this.form?.querySelector(`[${M}]`)!=null}isEngineResubmit(e){return this.form?.hasAttribute(p)?(this.snapshot.errors.length>0&&e.preventDefault(),!0):!1}resubmitIfSettled(){let e=this.form;if(!(!e||typeof e.requestSubmit!="function")&&!e.querySelector(`[${T}]`)&&!e.querySelector(`[${o}][data-invalid]`)){e.setAttribute(p,"");try{e.requestSubmit()}finally{e.removeAttribute(p)}}}};function x(i){return typeof i?.then=="function"}function $(i,e){return i.length===e.length&&i.every((t,r)=>t===e[r])}function G(i,e){return i.controlId===e.controlId&&i.valid===e.valid&&i.touched===e.touched&&i.dirty===e.dirty&&i.filled===e.filled&&i.count===e.count&&i.validity===e.validity&&i.errors.length===e.errors.length&&i.errors.every((t,r)=>t===e.errors[r])}export{z as CHARACTER_COUNT_ANNOUNCE_DELAY_MS,Y as ERROR_SUMMARY_RESCAN_EVENTS,j as FIELD_CHARACTER_COUNT_ATTRIBUTE,k as FIELD_CONTROL_ATTRIBUTE,g as FIELD_CONTROL_SELECTOR,_ as FIELD_DESCRIPTION_ATTRIBUTE,I as FIELD_ERROR_ATTRIBUTE,M as FIELD_ERROR_SUMMARY_ATTRIBUTE,f as FIELD_MESSAGE_ATTRIBUTE,u as FIELD_NAME_ATTRIBUTE,T as FIELD_PENDING_ATTRIBUTE,Q as FIELD_REQUIRED_INDICATOR_ATTRIBUTE,p as FIELD_RESUBMIT_ATTRIBUTE,o as FIELD_ROOT_ATTRIBUTE,F as FIELD_VALIDITY_CHANGE_EVENT,h as FORM_FIELD_ATTRIBUTE,D as FORM_MESSAGE_ATTRIBUTE,L as FieldController,w as NATIVE_INVALID_FALLBACK_MESSAGE,V as characterCountMessage,O as characterCountVisible,J as collectFieldErrors,X as errorSummaryScope,R as findFieldControl,ee as focusFieldTarget,te as focusInvalidControl,d as isFilled,K as joinFieldMessages,y as normalizeMessages,H as readControlValue,Z as resetFields,W as validateFields};
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
--skdx-space-10: 2.5rem;
|
|
49
49
|
--skdx-space-12: 3rem;
|
|
50
50
|
--skdx-space-16: 4rem;
|
|
51
|
+
--skdx-radius-default: var(--skdx-radius-md);
|
|
51
52
|
--skdx-radius-sm: 0.25rem;
|
|
52
53
|
--skdx-radius-inner: 0.375rem;
|
|
53
54
|
--skdx-radius-md: 0.5rem;
|
|
@@ -102,7 +103,7 @@
|
|
|
102
103
|
--skdx-item-height-lg: 2.5rem;
|
|
103
104
|
--skdx-item-gap: 2px;
|
|
104
105
|
--skdx-overlay-padding: var(--skdx-space-1);
|
|
105
|
-
--skdx-overlay-radius:
|
|
106
|
+
--skdx-overlay-radius: initial;
|
|
106
107
|
--skdx-overlay-min-width: 7.5rem;
|
|
107
108
|
--skdx-field-gap: var(--skdx-space-1);
|
|
108
109
|
--skdx-field-label-gap: var(--skdx-space-1);
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
color: var(--skdx-color-action-secondary-text);
|
|
55
55
|
background-color: var(--skdx-color-action-secondary-bg);
|
|
56
56
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-action-secondary-border);
|
|
57
|
-
border-radius: var(--skdx-radius-
|
|
57
|
+
border-radius: var(--skdx-radius-default);
|
|
58
58
|
|
|
59
59
|
font-size: var(--skdx-font-size-sm);
|
|
60
60
|
font-weight: var(--skdx-font-weight-medium);
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
background-color: var(--skdx-color-surface-raised);
|
|
19
19
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
20
|
-
border-radius: var(--skdx-radius-
|
|
20
|
+
border-radius: var(--skdx-radius-default);
|
|
21
21
|
|
|
22
22
|
cursor: pointer;
|
|
23
23
|
transition:
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
padding-inline: var(--skdx-space-2);
|
|
30
30
|
padding-block: var(--skdx-space-2);
|
|
31
31
|
|
|
32
|
-
border-radius: var(--skdx-radius-
|
|
32
|
+
border-radius: var(--skdx-radius-default);
|
|
33
33
|
font-size: var(--skdx-font-size-sm);
|
|
34
34
|
line-height: var(--skdx-font-line-height-normal);
|
|
35
35
|
color: var(--skdx-color-text-default);
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
min-block-size: var(--skdx-item-height-md);
|
|
61
61
|
padding-inline: var(--skdx-space-2);
|
|
62
62
|
padding-block: var(--skdx-space-2);
|
|
63
|
-
border-radius: var(--skdx-radius-
|
|
63
|
+
border-radius: var(--skdx-radius-default);
|
|
64
64
|
font-size: var(--skdx-font-size-sm);
|
|
65
65
|
color: var(--skdx-color-text-default);
|
|
66
66
|
cursor: pointer;
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
color: var(--skdx-color-text-default);
|
|
36
36
|
background-color: var(--skdx-color-surface-raised);
|
|
37
37
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
38
|
-
border-radius: var(--skdx-overlay-radius);
|
|
38
|
+
border-radius: var(--skdx-overlay-radius, var(--skdx-radius-default));
|
|
39
39
|
box-shadow: var(--skdx-shadow-overlay);
|
|
40
40
|
|
|
41
41
|
overflow: auto;
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
color: var(--skdx-color-field-text);
|
|
30
30
|
background-color: var(--skdx-color-field-bg);
|
|
31
31
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
32
|
-
border-radius: var(--skdx-radius-
|
|
32
|
+
border-radius: var(--skdx-radius-default);
|
|
33
33
|
|
|
34
34
|
font-size: var(--skdx-font-size-sm);
|
|
35
35
|
text-align: start;
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
inline-size: 100%;
|
|
19
19
|
|
|
20
20
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
21
|
-
border-radius: var(--skdx-radius-
|
|
21
|
+
border-radius: var(--skdx-radius-default);
|
|
22
22
|
/* Clips the first and last item's corners to the container's radius. */
|
|
23
23
|
overflow: hidden;
|
|
24
24
|
--skdx-focus-ring-offset: var(--skdx-focus-ring-offset-inset);
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
border: var(--skdx-border-width-thin) solid
|
|
26
26
|
var(--skdx-status-border, var(--skdx-color-status-neutral-border));
|
|
27
27
|
border-inline-start-width: var(--skdx-border-width-thicker);
|
|
28
|
-
border-radius: var(--skdx-radius-
|
|
28
|
+
border-radius: var(--skdx-radius-default);
|
|
29
29
|
|
|
30
30
|
font-size: var(--skdx-font-size-sm);
|
|
31
31
|
line-height: var(--skdx-font-line-height-normal);
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
color: currentColor;
|
|
99
99
|
background: transparent;
|
|
100
100
|
border: 0;
|
|
101
|
-
border-radius: var(--skdx-radius-
|
|
101
|
+
border-radius: var(--skdx-radius-default);
|
|
102
102
|
cursor: pointer;
|
|
103
103
|
}
|
|
104
104
|
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
color: var(--skdx-color-field-text);
|
|
34
34
|
background-color: var(--skdx-color-field-bg);
|
|
35
35
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
36
|
-
border-radius: var(--skdx-radius-
|
|
36
|
+
border-radius: var(--skdx-radius-default);
|
|
37
37
|
font-size: var(--skdx-font-size-sm);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
non-square source is cropped instead of distorted. */
|
|
23
23
|
overflow: hidden;
|
|
24
24
|
--skdx-focus-ring-offset: var(--skdx-focus-ring-offset-inset);
|
|
25
|
-
border-radius: var(--skdx-radius-
|
|
25
|
+
border-radius: var(--skdx-radius-default);
|
|
26
26
|
|
|
27
27
|
color: var(--skdx-color-text-muted);
|
|
28
28
|
background-color: var(--skdx-color-surface-sunken);
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
background-color: var(--skdx-status-bg, var(--skdx-color-status-neutral-bg));
|
|
32
32
|
border: var(--skdx-border-width-thin) solid
|
|
33
33
|
var(--skdx-status-border, var(--skdx-color-status-neutral-border));
|
|
34
|
-
border-radius: var(--skdx-radius-
|
|
34
|
+
border-radius: var(--skdx-radius-default);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/* data-variant (solid/outline/subtle), data-dot and data-status are three independent axes. */
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
padding-inline: var(--skdx-control-padding-md);
|
|
24
24
|
|
|
25
25
|
border: var(--skdx-border-width-thin) solid transparent;
|
|
26
|
-
border-radius: var(--skdx-radius-
|
|
26
|
+
border-radius: var(--skdx-radius-default);
|
|
27
27
|
|
|
28
28
|
font-size: var(--skdx-font-size-sm);
|
|
29
29
|
font-weight: var(--skdx-font-weight-medium);
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
color: var(--skdx-color-text-default);
|
|
34
34
|
background: transparent;
|
|
35
35
|
border: 0;
|
|
36
|
-
border-radius: var(--skdx-radius-
|
|
36
|
+
border-radius: var(--skdx-radius-default);
|
|
37
37
|
cursor: pointer;
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
color: var(--skdx-color-text-muted);
|
|
50
50
|
background: transparent;
|
|
51
51
|
border: 0;
|
|
52
|
-
border-radius: var(--skdx-radius-
|
|
52
|
+
border-radius: var(--skdx-radius-default);
|
|
53
53
|
cursor: pointer;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
color: var(--skdx-color-text-default);
|
|
116
116
|
background: transparent;
|
|
117
117
|
border: var(--skdx-border-width-thin) solid transparent;
|
|
118
|
-
border-radius: var(--skdx-radius-
|
|
118
|
+
border-radius: var(--skdx-radius-default);
|
|
119
119
|
|
|
120
120
|
font-size: var(--skdx-font-size-sm);
|
|
121
121
|
font-variant-numeric: tabular-nums;
|
|
@@ -126,7 +126,8 @@
|
|
|
126
126
|
flex: none;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
/* Keep hover at the same specificity as selection so the later selected/range rules win. */
|
|
130
|
+
:where(.skdx-calendar__cell):hover:where(:not([data-disabled])) {
|
|
130
131
|
background-color: var(--skdx-color-surface-hover);
|
|
131
132
|
}
|
|
132
133
|
|
|
@@ -145,6 +146,7 @@
|
|
|
145
146
|
|
|
146
147
|
/* Inside a selected range but not an endpoint. */
|
|
147
148
|
:where(.skdx-calendar__cell)[data-range-middle] {
|
|
149
|
+
color: var(--skdx-color-text-default);
|
|
148
150
|
background-color: var(--skdx-color-surface-selected);
|
|
149
151
|
border-radius: 0;
|
|
150
152
|
}
|
|
@@ -221,14 +223,14 @@
|
|
|
221
223
|
color: var(--skdx-color-text-default);
|
|
222
224
|
background: transparent;
|
|
223
225
|
border: var(--skdx-border-width-thin) solid transparent;
|
|
224
|
-
border-radius: var(--skdx-radius-
|
|
226
|
+
border-radius: var(--skdx-radius-default);
|
|
225
227
|
|
|
226
228
|
font-size: var(--skdx-font-size-sm);
|
|
227
229
|
font-variant-numeric: tabular-nums;
|
|
228
230
|
cursor: pointer;
|
|
229
231
|
}
|
|
230
232
|
|
|
231
|
-
:where(.skdx-calendar__view-cell):hover:not([data-disabled]) {
|
|
233
|
+
:where(.skdx-calendar__view-cell):hover:where(:not([data-disabled])) {
|
|
232
234
|
background-color: var(--skdx-color-surface-hover);
|
|
233
235
|
}
|
|
234
236
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
flex-direction: column;
|
|
15
15
|
|
|
16
16
|
--skdx-card-padding: var(--skdx-space-4);
|
|
17
|
-
--skdx-card-radius: var(--skdx-radius-
|
|
17
|
+
--skdx-card-radius: var(--skdx-radius-default);
|
|
18
18
|
|
|
19
19
|
background-color: var(--skdx-color-surface-raised);
|
|
20
20
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
color: var(--skdx-color-text-default);
|
|
60
60
|
background-color: var(--skdx-color-surface-raised);
|
|
61
61
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
62
|
-
border-radius: var(--skdx-radius-
|
|
62
|
+
border-radius: var(--skdx-radius-default);
|
|
63
63
|
box-shadow: var(--skdx-shadow-sm);
|
|
64
64
|
cursor: pointer;
|
|
65
65
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
background-color: var(--skdx-color-field-bg);
|
|
30
30
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
31
|
-
border-radius: var(--skdx-radius-
|
|
31
|
+
border-radius: var(--skdx-radius-default);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
:where(.skdx-chat-composer__field):focus-within {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
background-color: var(--skdx-color-surface-raised);
|
|
20
20
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
21
|
-
border-radius: var(--skdx-radius-
|
|
21
|
+
border-radius: var(--skdx-radius-default);
|
|
22
22
|
cursor: pointer;
|
|
23
23
|
|
|
24
24
|
transition:
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
color: transparent;
|
|
90
90
|
background-color: var(--skdx-color-field-bg);
|
|
91
91
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
92
|
-
border-radius: var(--skdx-radius-
|
|
92
|
+
border-radius: var(--skdx-radius-default);
|
|
93
93
|
font-size: var(--skdx-font-size-xs);
|
|
94
94
|
line-height: 1;
|
|
95
95
|
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
color: transparent;
|
|
27
27
|
background-color: var(--skdx-color-field-bg);
|
|
28
28
|
border: var(--skdx-border-width-thick) solid var(--skdx-color-field-border);
|
|
29
|
-
border-radius: var(--skdx-radius-
|
|
29
|
+
border-radius: var(--skdx-radius-default);
|
|
30
30
|
cursor: pointer;
|
|
31
31
|
|
|
32
32
|
transition:
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
color: var(--skdx-color-field-text);
|
|
55
55
|
background-color: var(--skdx-color-field-bg-readonly);
|
|
56
56
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
57
|
-
border-radius: var(--skdx-radius-
|
|
57
|
+
border-radius: var(--skdx-radius-default);
|
|
58
58
|
font-family: var(--skdx-font-family-mono);
|
|
59
59
|
font-size: var(--skdx-clipboard-input-font-size, var(--skdx-font-size-xs));
|
|
60
60
|
}
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
color: var(--skdx-color-text-default);
|
|
70
70
|
background-color: var(--skdx-color-action-secondary-bg);
|
|
71
71
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-action-secondary-border);
|
|
72
|
-
border-radius: var(--skdx-radius-
|
|
72
|
+
border-radius: var(--skdx-radius-default);
|
|
73
73
|
font-size: var(--skdx-clipboard-font-size, var(--skdx-font-size-sm));
|
|
74
74
|
cursor: pointer;
|
|
75
75
|
}
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
position: relative;
|
|
52
52
|
inline-size: 100%;
|
|
53
53
|
min-block-size: var(--skdx-color-picker-area-height, 8rem);
|
|
54
|
-
border-radius: var(--skdx-radius-
|
|
54
|
+
border-radius: var(--skdx-radius-default);
|
|
55
55
|
background-image:
|
|
56
56
|
linear-gradient(to top, #000, transparent), linear-gradient(to right, #fff, transparent);
|
|
57
57
|
background-color: hsl(var(--skdx-color-picker-hue, 0deg) 100% 50%);
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
block-size: var(--skdx-color-picker-swatch-size, var(--skdx-control-height-md));
|
|
196
196
|
background-color: var(--skdx-color-picker-swatch-value, transparent);
|
|
197
197
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
198
|
-
border-radius: var(--skdx-radius-
|
|
198
|
+
border-radius: var(--skdx-radius-default);
|
|
199
199
|
cursor: pointer;
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -226,7 +226,7 @@
|
|
|
226
226
|
color: var(--skdx-color-text-default);
|
|
227
227
|
background-color: var(--skdx-color-action-secondary-bg);
|
|
228
228
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-action-secondary-border);
|
|
229
|
-
border-radius: var(--skdx-radius-
|
|
229
|
+
border-radius: var(--skdx-radius-default);
|
|
230
230
|
cursor: pointer;
|
|
231
231
|
}
|
|
232
232
|
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
color: var(--skdx-color-field-text);
|
|
281
281
|
background-color: var(--skdx-color-field-bg);
|
|
282
282
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
283
|
-
border-radius: var(--skdx-radius-
|
|
283
|
+
border-radius: var(--skdx-radius-default);
|
|
284
284
|
font-family: var(--skdx-font-family-mono);
|
|
285
285
|
font-size: var(--skdx-font-size-xs);
|
|
286
286
|
}
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
:where(.skdx-combobox__input),
|
|
43
43
|
:where(.skdx-combobox__input)[data-shape='rounded'] {
|
|
44
|
-
--skdx-combobox-radius: var(--skdx-radius-
|
|
44
|
+
--skdx-combobox-radius: var(--skdx-radius-default);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
:where(.skdx-combobox__input)[data-shape='square'] {
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
color: var(--skdx-color-text-muted);
|
|
97
97
|
background-color: var(--skdx-color-field-bg);
|
|
98
98
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-field-border);
|
|
99
|
-
border-radius: var(--skdx-radius-
|
|
99
|
+
border-radius: var(--skdx-radius-default);
|
|
100
100
|
cursor: pointer;
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
--skdx-focus-ring-offset: var(--skdx-focus-ring-offset-inset);
|
|
18
18
|
background-color: var(--skdx-color-surface-raised);
|
|
19
19
|
border: var(--skdx-border-width-thin) solid var(--skdx-color-border-default);
|
|
20
|
-
border-radius: var(--skdx-overlay-radius);
|
|
20
|
+
border-radius: var(--skdx-overlay-radius, var(--skdx-radius-default));
|
|
21
21
|
box-shadow: var(--skdx-shadow-overlay);
|
|
22
22
|
}
|
|
23
23
|
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
gap: var(--skdx-space-2);
|
|
62
62
|
padding-inline: var(--skdx-space-3);
|
|
63
63
|
padding-block: var(--skdx-space-2);
|
|
64
|
-
border-radius: var(--skdx-radius-
|
|
64
|
+
border-radius: var(--skdx-radius-default);
|
|
65
65
|
color: var(--skdx-color-text-default);
|
|
66
66
|
text-decoration: none;
|
|
67
67
|
}
|