@spfx-fast/sharepoint-ui 0.4.1 → 0.4.3
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/AGENTS.md +23 -3
- package/QUICKSTART.md +133 -0
- package/README.md +21 -878
- package/components.json +178 -33
- package/dist/appearance.js +4 -4
- package/dist/elements/alert.js +26 -2
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/carousel.js +5 -2
- package/dist/elements/color-picker.js +1 -1
- package/dist/elements/combobox.js +5 -5
- package/dist/elements/data-grid-model.d.ts +3 -0
- package/dist/elements/data-grid.d.ts +2 -1
- package/dist/elements/data-grid.js +19 -10
- package/dist/elements/date-picker.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/floating-position.d.ts +10 -0
- package/dist/elements/floating-position.js +53 -0
- package/dist/elements/info.js +1 -1
- package/dist/elements/input.js +2 -2
- package/dist/elements/link.js +1 -1
- package/dist/elements/message-bar.js +33 -5
- package/dist/elements/nav.js +4 -1
- package/dist/elements/overflow.d.ts +1 -0
- package/dist/elements/overflow.js +2 -2
- package/dist/elements/popover.js +1 -1
- package/dist/elements/rating.js +3 -3
- package/dist/elements/rich-text-editor.d.ts +15 -1
- package/dist/elements/rich-text-editor.js +938 -79
- package/dist/elements/search.js +3 -10
- package/dist/elements/select.js +2 -2
- package/dist/elements/shared.d.ts +4 -1
- package/dist/elements/shared.js +14 -1
- package/dist/elements/sharepoint-field-basic-controls.d.ts +1 -0
- package/dist/elements/sharepoint-field-basic-controls.js +14 -0
- package/dist/elements/sharepoint-fields.d.ts +29 -0
- package/dist/elements/sharepoint-fields.js +460 -0
- package/dist/elements/spin-button.js +2 -2
- package/dist/elements/tag-picker.js +29 -11
- package/dist/elements/textarea.js +2 -2
- package/dist/elements/toaster.js +2 -1
- package/dist/elements/tooltip.js +18 -1
- package/dist/elements/tree.js +1 -1
- package/dist/elements.d.ts +3 -2
- package/dist/elements.js +4 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -2
- package/dist/react.d.ts +188 -19
- package/dist/react.js +321 -61
- package/dist/sharepoint-fields.d.ts +135 -0
- package/dist/sharepoint-fields.js +402 -0
- package/dist/theme.d.ts +9 -1
- package/dist/theme.js +78 -1
- package/package.json +11 -2
- package/skills/sharepoint-ui/SKILL.md +1 -1
- package/skills/sharepoint-ui/references/sharepoint-patterns.md +1 -1
|
@@ -136,7 +136,7 @@ export function defineColorArea() {
|
|
|
136
136
|
render() {
|
|
137
137
|
const shadow = this.attachShadow({ mode: "open" });
|
|
138
138
|
const style = document.createElement("style");
|
|
139
|
-
style.textContent = `${base}:host{display:block;min-width:0}.area{position:relative;width:min(260px,100%);height:160px;border:1px solid var(--spui-ui-stroke,var(--colorNeutralStroke1,#8a8886));border-radius:var(--picker-radius,var(--spui-control-radius,8px));background-image:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,hsl(var(--picker-hue,0deg) 100% 50%));touch-action:none;cursor:crosshair}.thumb{position:absolute;inset-inline-start:var(--picker-saturation,0%);top:var(--picker-brightness,100%);width:14px;height:14px;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 1px #000;transform:translate(-50%,-50%);pointer-events:none}.area:focus-within{
|
|
139
|
+
style.textContent = `${base}:host{display:block;min-width:0}.area{box-sizing:border-box;position:relative;width:min(260px,100%);height:160px;border:1px solid var(--spui-ui-stroke,var(--colorNeutralStroke1,#8a8886));border-radius:var(--picker-radius,var(--spui-control-radius,8px));background-image:linear-gradient(to top,#000,transparent),linear-gradient(to right,#fff,hsl(var(--picker-hue,0deg) 100% 50%));touch-action:none;cursor:crosshair}.thumb{position:absolute;inset-inline-start:var(--picker-saturation,0%);top:var(--picker-brightness,100%);width:14px;height:14px;border:2px solid #fff;border-radius:50%;box-shadow:0 0 0 1px #000;transform:translate(-50%,-50%);pointer-events:none}.area:focus-within{border-width:2px;border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline:0;box-shadow:none}.inputs{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.inputs slot{display:contents}.inputs input{position:absolute;width:1px;height:1px}@media(forced-colors:active){.area{border-color:FieldText}.area:focus-within{border-color:Highlight;outline:0}.thumb{border-color:Canvas;box-shadow:0 0 0 1px CanvasText}}`;
|
|
140
140
|
this.area = document.createElement("div");
|
|
141
141
|
this.area.className = "area";
|
|
142
142
|
this.area.setAttribute("role", "group");
|
|
@@ -4,7 +4,7 @@ export function defineCombobox() {
|
|
|
4
4
|
return;
|
|
5
5
|
class SpuiCombobox extends HTMLElement {
|
|
6
6
|
static formAssociated = true;
|
|
7
|
-
static observedAttributes = ["label", "value", "selected-value", "selected-options", "default-selected-options", "multiselect", "disabled", "required", "name", "placeholder", "allow-freeform", "read-only", "button-trigger", "open", "default-open", "clearable", "clear-label", "disable-auto-focus", "appearance", "size", "positioning", "inline-popup", "no-results", "remove-selected-label", "selected-label", "aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"];
|
|
7
|
+
static observedAttributes = ["label", "value", "selected-value", "selected-options", "default-selected-options", "multiselect", "disabled", "required", "required-message", "name", "placeholder", "allow-freeform", "read-only", "button-trigger", "open", "default-open", "clearable", "clear-label", "disable-auto-focus", "appearance", "size", "positioning", "inline-popup", "no-results", "remove-selected-label", "selected-label", "aria-label", "aria-labelledby", "aria-description", "aria-describedby", "aria-invalid"];
|
|
8
8
|
internals;
|
|
9
9
|
observer;
|
|
10
10
|
positionEvents;
|
|
@@ -304,7 +304,7 @@ export function defineCombobox() {
|
|
|
304
304
|
this.internals?.setFormValue(formValue || null, this.hasAttribute("multiselect") ? JSON.stringify(this.selectedOptionsState) : typeof formValue === "string" ? formValue : null);
|
|
305
305
|
const missing = this.hasAttribute("required") && (this.hasAttribute("multiselect") ? this.selectedOptionsState.length === 0 : !formValue);
|
|
306
306
|
try {
|
|
307
|
-
this.internals?.setValidity(missing ? { valueMissing: true } : {}, missing ? "Choose an option." : "", this.hasAttribute("button-trigger") ? undefined : this.getInput() ?? undefined);
|
|
307
|
+
this.internals?.setValidity(missing ? { valueMissing: true } : {}, missing ? this.getAttribute("required-message") || "Choose an option." : "", this.hasAttribute("button-trigger") ? undefined : this.getInput() ?? undefined);
|
|
308
308
|
}
|
|
309
309
|
catch { /* Keep native input semantics if an engine rejects the validity anchor. */ }
|
|
310
310
|
}
|
|
@@ -998,10 +998,10 @@ export function defineCombobox() {
|
|
|
998
998
|
empty.hidden = true;
|
|
999
999
|
wrapper.append(selected, triggerSlot, inputSlot, expand, clearSlot, listboxSlot, empty);
|
|
1000
1000
|
const style = document.createElement("style");
|
|
1001
|
-
style.textContent = `${base}:host{display:grid;gap:var(--spui-control-gap,6px)}label{font-size:14px;font-weight:600;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit))}.control{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:4px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,var(--colorNeutralStroke1,#8a8886))));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,var(--colorNeutralBackground1,#fff))));box-shadow:var(--spui-control-shadow,none)}.selected{display:flex;flex-wrap:wrap;gap:4px;min-width:0}.selected[hidden]{display:none}.tag{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 8px;border:1px solid var(--spui-tag-border,var(--spui-ui-stroke,#d1d1d1));border-radius:var(--spui-tag-radius,4px);background:var(--spui-tag-background,var(--spui-ui-surface-hover,#f5f5f5));color:var(--spui-ui-text,inherit);font-size:.9em}.remove,.clear{width:24px;height:24px;border:0;border-radius:3px;background:transparent;color:inherit;cursor:pointer}.remove:hover,.clear:hover{background:var(--spui-ui-surface-hover,#f5f5f5)}input{box-sizing:border-box;flex:1 1 120px;min-width:80px;min-height:calc(var(--spui-control-height,36px) - 10px);padding:4px 8px;border:0;outline:0;background:transparent;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}input:focus-visible{outline:2px solid var(--spui-focus-ring,#005a9e);outline-offset:1px}input:disabled{opacity:.55}ul{position:absolute;z-index:var(--spui-layer-dropdown,20);top:calc(100% + 4px);inset-inline:0;box-sizing:border-box;max-height:240px;overflow:auto;margin:0;padding:4px;list-style:none;border:1px solid var(--spui-ui-stroke,#d1d1d1);border-radius:var(--spui-card-radius,8px);background:var(--spui-ui-surface,#fff);box-shadow:var(--spui-card-shadow,0 4px 14px #0002)}:host([positioning^=above]) ul{top:auto;bottom:calc(100% + 4px)}ul[hidden]{display:none}.option-group{display:grid;gap:2px;padding-block:2px}.group-label{padding:6px 10px;color:var(--spui-ui-muted,inherit);font-size:12px;font-weight:600}[role=option],li.empty{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:var(--spui-control-radius,4px);color:var(--spui-ui-text,inherit);cursor:pointer}[role=option][data-active=true],[role=option][aria-selected=true]{background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.check{display:inline-grid;place-items:center;width:16px;height:16px;flex:none;border:1px solid var(--spui-ui-stroke,#8a8886);border-radius:3px;color:var(--spui-ui-accent,#0f6cbd);font-size:12px}[role=option][aria-selected=true] .check{border-color:var(--spui-ui-accent,#0f6cbd);background:var(--spui-ui-canvas,#f5f5f5)}[role=option][aria-disabled=true]{opacity:.5;cursor:not-allowed}li.empty{color:var(--spui-ui-muted,inherit);cursor:default}:host([size=small]) input{min-height:30px}:host([size=large]) input{min-height:44px}:host([appearance=filled-darker]) input{background:var(--spui-ui-surface-sunken,#f0f0f0)}:host([appearance=filled-lighter]) input{background:var(--spui-ui-surface,#fff)}:host([appearance=underline]) input{border-radius:0;border-width:0 0 1px}@media(forced-colors:active){.control,ul{border-color:CanvasText;box-shadow:none}.tag{border-color:CanvasText}.check{border-color:CanvasText}li[role=option][data-active=true]{outline:1px solid Highlight}}:host(:not([multiselect])) .control{display:block;gap:0;padding:0;border:0;background:transparent;box-shadow:none}:host(:not([multiselect])) input{box-sizing:border-box;width:100%;min-height:var(--spui-control-height,36px);padding:8px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff)));box-shadow:var(--spui-control-shadow,none);color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}:host(:not([multiselect])) input:focus-visible{
|
|
1002
|
-
style.textContent += ".expand{display:inline-flex;align-items:center;justify-content:center;flex:none;color:inherit}.expand[hidden]{display:none}::slotted([slot=clear-button]){cursor:pointer}:host([read-only]) .expand,:host([button-trigger]) .expand{position:absolute;inset-inline-end:6px;top:6px}:host([read-only]) .clear,:host([read-only]) ::slotted([slot=clear-button]),:host([button-trigger]) .clear,:host([button-trigger]) ::slotted([slot=clear-button]){position:absolute;inset-inline-end:32px;top:6px}:host([read-only]) input{width:calc(100% - 56px)}:host([read-only]:not([clearable])) input{width:calc(100% - 28px)}.trigger,::slotted([slot=button]){box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:var(--spui-control-height,36px);padding:8px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff)));box-shadow:var(--spui-control-shadow,none);color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit;text-align:start;cursor:pointer}.trigger:focus-visible
|
|
1001
|
+
style.textContent = `${base}:host{display:grid;gap:var(--spui-control-gap,6px)}label{font-size:14px;font-weight:600;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit))}.control{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:4px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,var(--colorNeutralStroke1,#8a8886))));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,var(--colorNeutralBackground1,#fff))));box-shadow:var(--spui-control-shadow,none)}.selected{display:flex;flex-wrap:wrap;gap:4px;min-width:0}.selected[hidden]{display:none}.tag{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 8px;border:1px solid var(--spui-tag-border,var(--spui-ui-stroke,#d1d1d1));border-radius:var(--spui-tag-radius,4px);background:var(--spui-tag-background,var(--spui-ui-surface-hover,#f5f5f5));color:var(--spui-ui-text,inherit);font-size:.9em}.remove,.clear{width:24px;height:24px;border:0;border-radius:3px;background:transparent;color:inherit;cursor:pointer}.remove:hover,.clear:hover{background:var(--spui-ui-surface-hover,#f5f5f5)}input{box-sizing:border-box;flex:1 1 120px;min-width:80px;min-height:calc(var(--spui-control-height,36px) - 10px);padding:4px 8px;border:0;outline:0;background:transparent;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}input:focus-visible{outline:2px solid var(--spui-focus-ring,#005a9e);outline-offset:1px}input:disabled{opacity:.55}ul{position:absolute;z-index:var(--spui-layer-dropdown,20);top:calc(100% + 4px);inset-inline:0;box-sizing:border-box;max-height:240px;overflow:auto;margin:0;padding:4px;list-style:none;border:1px solid var(--spui-ui-stroke,#d1d1d1);border-radius:var(--spui-card-radius,8px);background:var(--spui-ui-surface,#fff);box-shadow:var(--spui-card-shadow,0 4px 14px #0002)}:host([positioning^=above]) ul{top:auto;bottom:calc(100% + 4px)}ul[hidden]{display:none}.option-group{display:grid;gap:2px;padding-block:2px}.group-label{padding:6px 10px;color:var(--spui-ui-muted,inherit);font-size:12px;font-weight:600}[role=option],li.empty{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:var(--spui-control-radius,4px);color:var(--spui-ui-text,inherit);cursor:pointer}[role=option][data-active=true],[role=option][aria-selected=true]{background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.check{display:inline-grid;place-items:center;width:16px;height:16px;flex:none;border:1px solid var(--spui-ui-stroke,#8a8886);border-radius:3px;color:var(--spui-ui-accent,#0f6cbd);font-size:12px}[role=option][aria-selected=true] .check{border-color:var(--spui-ui-accent,#0f6cbd);background:var(--spui-ui-canvas,#f5f5f5)}[role=option][aria-disabled=true]{opacity:.5;cursor:not-allowed}li.empty{color:var(--spui-ui-muted,inherit);cursor:default}:host([size=small]) input{min-height:30px}:host([size=large]) input{min-height:44px}:host([appearance=filled-darker]) input{background:var(--spui-ui-surface-sunken,#f0f0f0)}:host([appearance=filled-lighter]) input{background:var(--spui-ui-surface,#fff)}:host([appearance=underline]) input{border-radius:0;border-width:0 0 1px}@media(forced-colors:active){.control,ul{border-color:CanvasText;box-shadow:none}.tag{border-color:CanvasText}.check{border-color:CanvasText}li[role=option][data-active=true]{outline:1px solid Highlight}}:host(:not([multiselect])) .control{display:block;gap:0;padding:0;border:0;background:transparent;box-shadow:none}:host(:not([multiselect])) input{box-sizing:border-box;width:100%;min-height:var(--spui-control-height,36px);padding:8px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff)));box-shadow:var(--spui-control-shadow,none);color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}:host(:not([multiselect])) input:focus-visible{border-width:2px;border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline:0}:host([appearance=underline]:not([multiselect])) input:focus-visible{border-width:0 0 2px}:host([multiselect]) .control:focus-within{border-width:2px;border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));box-shadow:none}:host([multiselect]) .control input:focus-visible{outline:0}:host([aria-invalid]:not([aria-invalid=false])) .control,:host([aria-invalid]:not([aria-invalid=false])) input,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=input]),:host([aria-invalid]:not([aria-invalid=false])) .trigger,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=button]){border-color:var(--spui-input-invalid-border,var(--spui-ui-danger,var(--colorPaletteRedBorder2,#c50f1f)))}:host([aria-invalid]:not([aria-invalid=false])) input:focus-visible,:host([aria-invalid]:not([aria-invalid=false])) .trigger:focus-visible,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=input]:focus-visible),:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=button]:focus-visible){border-color:var(--spui-input-invalid-border,var(--spui-ui-danger,var(--colorPaletteRedBorder2,#c50f1f)))}@media(forced-colors:active){:host(:not([multiselect])) input{border-color:FieldText;background:Field;color:FieldText}:host(:not([multiselect])) input:focus-visible{border-color:Highlight}:host([multiselect]) .control:focus-within{border-color:Highlight}:host([aria-invalid]:not([aria-invalid=false])) .control,:host([aria-invalid]:not([aria-invalid=false])) input,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=input]),:host([aria-invalid]:not([aria-invalid=false])) .trigger,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=button]){border-color:CanvasText}:host([aria-invalid]:not([aria-invalid=false])) input:focus-visible,:host([aria-invalid]:not([aria-invalid=false])) .trigger:focus-visible,:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=input]:focus-visible),:host([aria-invalid]:not([aria-invalid=false])) ::slotted([slot=button]:focus-visible){border-color:Highlight!important}:host(:not([multiselect])) ::slotted([slot=input]:focus-visible){border-color:Highlight!important}:host([button-trigger]) ::slotted([slot=button]:focus-visible){border-color:Highlight!important}}`;
|
|
1002
|
+
style.textContent += ".expand{display:inline-flex;align-items:center;justify-content:center;flex:none;color:inherit}.expand[hidden]{display:none}::slotted([slot=clear-button]){cursor:pointer}:host([read-only]) .expand,:host([button-trigger]) .expand{position:absolute;inset-inline-end:6px;top:6px}:host([read-only]) .clear,:host([read-only]) ::slotted([slot=clear-button]),:host([button-trigger]) .clear,:host([button-trigger]) ::slotted([slot=clear-button]){position:absolute;inset-inline-end:32px;top:6px}:host([read-only]) input{width:calc(100% - 56px)}:host([read-only]:not([clearable])) input{width:calc(100% - 28px)}.trigger,::slotted([slot=button]){box-sizing:border-box;display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;min-height:var(--spui-control-height,36px);padding:8px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff)));box-shadow:var(--spui-control-shadow,none);color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit;text-align:start;cursor:pointer}.trigger:focus-visible{border-width:2px;border-color:var(--spui-focus-ring,var(--spui-semantic-focus-border,#005a9e));outline:0;outline-offset:0;box-shadow:none}::slotted([slot=button]:focus-visible){border-width:2px!important;border-color:var(--spui-focus-ring,var(--spui-semantic-focus-border,#005a9e))!important;outline:0!important;outline-offset:0;box-shadow:none!important}:host([appearance=underline]) .trigger:focus-visible,:host([appearance=underline]) ::slotted([slot=button]:focus-visible){border-width:0 0 2px!important}.trigger:disabled,::slotted([slot=button][disabled]){opacity:.55;cursor:not-allowed}:host([button-trigger][size=small]) .trigger,:host([button-trigger][size=small]) ::slotted([slot=button]){min-height:30px}:host([button-trigger][size=large]) .trigger,:host([button-trigger][size=large]) ::slotted([slot=button]){min-height:44px}:host([button-trigger]) .trigger-value{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(forced-colors:active){.trigger,:host([button-trigger]) ::slotted([slot=button]){border-color:ButtonText;background:ButtonFace;color:ButtonText}.trigger:focus-visible,:host([button-trigger]) ::slotted([slot=button]:focus-visible){border-color:Highlight!important;outline:0!important}}";
|
|
1003
1003
|
style.textContent = style.textContent?.replaceAll("li.empty", ".empty") ?? "";
|
|
1004
|
-
style.textContent += `::slotted([slot=input]){box-sizing:border-box;flex:1 1 120px;min-width:80px;min-height:calc(var(--spui-control-height,36px) - 10px);padding:4px 8px;border:0;outline:0;background:transparent;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}::slotted([slot=input]:focus-visible){outline:
|
|
1004
|
+
style.textContent += `::slotted([slot=input]){box-sizing:border-box;flex:1 1 120px;min-width:80px;min-height:calc(var(--spui-control-height,36px) - 10px);padding:4px 8px;border:0;outline:0;background:transparent;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}:host([multiselect]) ::slotted([slot=input]){border:0!important;outline:0!important;box-shadow:none!important}::slotted([slot=input]:focus-visible){border:0!important;outline:0!important;outline-offset:0;box-shadow:none!important}:host(:not([multiselect])) ::slotted([slot=input]:focus-visible){border-style:solid!important;border-width:2px!important;border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4))!important}:host([appearance=underline]:not([multiselect])) ::slotted([slot=input]:focus-visible){border-width:0 0 2px!important}:host(:not([multiselect])) ::slotted([slot=input]){box-sizing:border-box;width:100%;min-height:var(--spui-control-height,36px);padding:8px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886)));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff)));color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}`;
|
|
1005
1005
|
shadow.replaceChildren(style, label, wrapper);
|
|
1006
1006
|
this.bindInput();
|
|
1007
1007
|
this.syncExpandIcon();
|
|
@@ -93,6 +93,9 @@ export type DataGridCellEdit<T = unknown> = {
|
|
|
93
93
|
previousValue: unknown;
|
|
94
94
|
value: DataGridEditValue;
|
|
95
95
|
};
|
|
96
|
+
export type DataGridCellEditError<T = unknown> = DataGridCellEdit<T> & {
|
|
97
|
+
error: string;
|
|
98
|
+
};
|
|
96
99
|
/** Bound row sizes to keep a consumer callback from creating pathological virtual scroll extents. */
|
|
97
100
|
export declare function clampDataGridRowHeight(height: number | undefined, estimate: number): number;
|
|
98
101
|
export declare function getDataGridCellValue<T>(item: T, column: DataGridColumn<T>): unknown;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DataGridCellEdit, type DataGridColumn, type DataGridDataSource, type DataGridColumnSizingOptions, type DataGridFocusMode, type DataGridSelectionAppearance, type DataGridSelectionModel } from "./data-grid-model.js";
|
|
1
|
+
import { type DataGridCellEdit, type DataGridCellEditError, type DataGridColumn, type DataGridDataSource, type DataGridColumnSizingOptions, type DataGridFocusMode, type DataGridSelectionAppearance, type DataGridSelectionModel } from "./data-grid-model.js";
|
|
2
2
|
export type DataGridCellRenderer<T = unknown> = (item: T, column: DataGridColumn<T>, rowIndex: number) => Node | string | number | null;
|
|
3
3
|
export type DataGridRowHeightGetter<T = unknown> = (item: T, rowIndex: number) => number;
|
|
4
4
|
export type DataGridCellsEditHandler = (edits: readonly DataGridCellEdit[]) => void | Promise<void>;
|
|
@@ -19,6 +19,7 @@ export interface SharePointDataGridElement extends HTMLElement {
|
|
|
19
19
|
onDataSourceSelectionChange?: DataGridSourceSelectionHandler;
|
|
20
20
|
getRowHeight?: DataGridRowHeightGetter;
|
|
21
21
|
onCellsEdit?: DataGridCellsEditHandler;
|
|
22
|
+
onCellEditError?: (error: DataGridCellEditError) => void;
|
|
22
23
|
}
|
|
23
24
|
declare global {
|
|
24
25
|
interface HTMLElementTagNameMap {
|
|
@@ -7,7 +7,7 @@ export function defineDataGrid() {
|
|
|
7
7
|
if (customElements.get("spui-data-grid"))
|
|
8
8
|
return;
|
|
9
9
|
class SpuiDataGrid extends HTMLElement {
|
|
10
|
-
static observedAttributes = ["aria-label", "label", "focus-mode", "selection-mode", "selection-appearance", "subtle-selection", "auto-fit-columns", "container-width-offset", "row-height", "overscan", "virtualize-columns", "select-label", "select-all-label", "empty-label", "no-results-label", "filterable", "filter-label", "sort-priority-label", "resizable-columns", "resize-label", "reorderable-columns", "reorder-label", "group-by", "empty-group-label", "expand-group-label", "collapse-group-label", "row-label", "edit-hint"];
|
|
10
|
+
static observedAttributes = ["aria-label", "label", "focus-mode", "selection-mode", "selection-appearance", "subtle-selection", "auto-fit-columns", "container-width-offset", "row-height", "overscan", "virtualize-columns", "select-label", "select-all-label", "empty-label", "no-results-label", "loading-label", "load-error-label", "edit-error-label", "filterable", "filter-label", "sort-priority-label", "resizable-columns", "resize-label", "reorderable-columns", "reorder-label", "reorder-hint-label", "group-by", "empty-group-label", "expand-group-label", "collapse-group-label", "row-label", "edit-hint", "selection-copied-label", "copy-failed-label", "paste-one-label", "paste-many-label", "paste-failed-label"];
|
|
11
11
|
data = [];
|
|
12
12
|
source;
|
|
13
13
|
sourceUnsubscribe;
|
|
@@ -85,6 +85,7 @@ export function defineDataGrid() {
|
|
|
85
85
|
editedValues = new Map();
|
|
86
86
|
editingCell;
|
|
87
87
|
editCallback;
|
|
88
|
+
editErrorCallback;
|
|
88
89
|
cellsEditCallback;
|
|
89
90
|
dataSourceGroupToggleCallback;
|
|
90
91
|
dataSourceSelectionCallback;
|
|
@@ -187,6 +188,8 @@ export function defineDataGrid() {
|
|
|
187
188
|
set collapsedGroupKeys(value) { this.collapsedGroups = new Set(value ?? []); this.paint(true); }
|
|
188
189
|
get onCellEdit() { return this.editCallback; }
|
|
189
190
|
set onCellEdit(value) { this.editCallback = value; }
|
|
191
|
+
get onCellEditError() { return this.editErrorCallback; }
|
|
192
|
+
set onCellEditError(value) { this.editErrorCallback = value; }
|
|
190
193
|
get validateCellEdit() { return this.editValidator; }
|
|
191
194
|
set validateCellEdit(value) { this.editValidator = value; }
|
|
192
195
|
get onCellsEdit() { return this.cellsEditCallback; }
|
|
@@ -210,6 +213,9 @@ export function defineDataGrid() {
|
|
|
210
213
|
}
|
|
211
214
|
disconnectedCallback() { cancelAnimationFrame(this.frame); this.frame = 0; this.resizeObserver?.disconnect(); this.sourceRequest?.controller.abort(); this.sourceRequest = undefined; this.clipboardController?.abort(); this.clipboardController = undefined; this.sourceUnsubscribe?.(); this.sourceUnsubscribe = undefined; }
|
|
212
215
|
attributeChangedCallback() { this.renderFilter(); this.renderHeader(); this.initializeColumnWidths(); this.paint(true); }
|
|
216
|
+
localizedMessage(attribute, fallback, values = {}) {
|
|
217
|
+
return Object.entries(values).reduce((message, [key, value]) => message.replaceAll(`{${key}}`, value), this.getAttribute(attribute) ?? fallback);
|
|
218
|
+
}
|
|
213
219
|
render() {
|
|
214
220
|
const shadow = this.attachShadow({ mode: "open" });
|
|
215
221
|
const style = document.createElement("style");
|
|
@@ -372,7 +378,7 @@ export function defineDataGrid() {
|
|
|
372
378
|
this.failedSourceRange = key;
|
|
373
379
|
const error = new Error("loadRange resolved before every requested row was available");
|
|
374
380
|
if (this.reorderStatus)
|
|
375
|
-
this.reorderStatus.textContent = error.
|
|
381
|
+
this.reorderStatus.textContent = this.localizedMessage("load-error-label", "Data could not be loaded.");
|
|
376
382
|
this.viewport?.setAttribute("aria-busy", "false");
|
|
377
383
|
this.dispatchEvent(new CustomEvent("spui-data-load-error", { detail: { error, start, end }, bubbles: true, composed: true }));
|
|
378
384
|
return;
|
|
@@ -389,7 +395,7 @@ export function defineDataGrid() {
|
|
|
389
395
|
this.sourceRequest = undefined;
|
|
390
396
|
this.failedSourceRange = key;
|
|
391
397
|
if (this.reorderStatus)
|
|
392
|
-
this.reorderStatus.textContent =
|
|
398
|
+
this.reorderStatus.textContent = this.localizedMessage("load-error-label", "Data could not be loaded.");
|
|
393
399
|
this.viewport?.setAttribute("aria-busy", "false");
|
|
394
400
|
this.dispatchEvent(new CustomEvent("spui-data-load-error", { detail: { error, start, end }, bubbles: true, composed: true }));
|
|
395
401
|
});
|
|
@@ -476,7 +482,7 @@ export function defineDataGrid() {
|
|
|
476
482
|
grip.dataset.reorderColumn = column.id;
|
|
477
483
|
grip.draggable = true;
|
|
478
484
|
grip.setAttribute("aria-label", `${this.getAttribute("reorder-label") || "Reorder column"} ${column.label}`);
|
|
479
|
-
grip.title =
|
|
485
|
+
grip.title = this.localizedMessage("reorder-hint-label", "Reorder {column}; use Alt+Shift+Arrow keys", { column: column.label });
|
|
480
486
|
grip.textContent = "⠿";
|
|
481
487
|
cell.append(grip);
|
|
482
488
|
}
|
|
@@ -1024,11 +1030,14 @@ export function defineDataGrid() {
|
|
|
1024
1030
|
}
|
|
1025
1031
|
catch (reason) {
|
|
1026
1032
|
editing.saving = false;
|
|
1027
|
-
|
|
1033
|
+
const message = reason instanceof Error ? reason.message : String(reason || "The value could not be saved.");
|
|
1034
|
+
editing.error = this.getAttribute("edit-error-label") || "The value could not be saved.";
|
|
1028
1035
|
if (input) {
|
|
1029
1036
|
input.disabled = false;
|
|
1030
1037
|
input.removeAttribute("aria-busy");
|
|
1031
1038
|
}
|
|
1039
|
+
this.editErrorCallback?.({ item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message });
|
|
1040
|
+
this.dispatchEvent(new CustomEvent("spui-cell-edit-error", { detail: { item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message }, bubbles: true, composed: true }));
|
|
1032
1041
|
this.showEditError(editing);
|
|
1033
1042
|
}
|
|
1034
1043
|
}
|
|
@@ -1049,7 +1058,7 @@ export function defineDataGrid() {
|
|
|
1049
1058
|
error.setAttribute("role", "alert");
|
|
1050
1059
|
cell.append(error);
|
|
1051
1060
|
}
|
|
1052
|
-
error.textContent = editing.error || "The value could not be saved.";
|
|
1061
|
+
error.textContent = editing.error || this.getAttribute("edit-error-label") || "The value could not be saved.";
|
|
1053
1062
|
requestAnimationFrame(() => input.focus());
|
|
1054
1063
|
}
|
|
1055
1064
|
currentEditValue(item, rowId, column) {
|
|
@@ -1101,13 +1110,13 @@ export function defineDataGrid() {
|
|
|
1101
1110
|
});
|
|
1102
1111
|
void writeDataGridClipboardText(text).then(() => {
|
|
1103
1112
|
if (this.clipboardController === controller && this.reorderStatus)
|
|
1104
|
-
this.reorderStatus.textContent = "Selection copied.";
|
|
1113
|
+
this.reorderStatus.textContent = this.localizedMessage("selection-copied-label", "Selection copied.");
|
|
1105
1114
|
}, reason => {
|
|
1106
1115
|
if (controller.signal.aborted)
|
|
1107
1116
|
return;
|
|
1108
1117
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
1109
1118
|
if (this.reorderStatus)
|
|
1110
|
-
this.reorderStatus.textContent =
|
|
1119
|
+
this.reorderStatus.textContent = this.localizedMessage("copy-failed-label", "Copy failed.");
|
|
1111
1120
|
this.dispatchEvent(new CustomEvent("spui-clipboard-error", { detail: { operation: "copy", message }, bubbles: true, composed: true }));
|
|
1112
1121
|
});
|
|
1113
1122
|
}
|
|
@@ -1194,7 +1203,7 @@ export function defineDataGrid() {
|
|
|
1194
1203
|
this.dispatchEvent(new CustomEvent("spui-cell-edit", { detail: edit, bubbles: true, composed: true }));
|
|
1195
1204
|
}
|
|
1196
1205
|
if (this.reorderStatus)
|
|
1197
|
-
this.reorderStatus.textContent =
|
|
1206
|
+
this.reorderStatus.textContent = this.localizedMessage(edits.length === 1 ? "paste-one-label" : "paste-many-label", edits.length === 1 ? "Pasted {count} cell." : "Pasted {count} cells.", { count: String(edits.length) });
|
|
1198
1207
|
this.paint(true);
|
|
1199
1208
|
}
|
|
1200
1209
|
catch (reason) {
|
|
@@ -1202,7 +1211,7 @@ export function defineDataGrid() {
|
|
|
1202
1211
|
return;
|
|
1203
1212
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
1204
1213
|
if (this.reorderStatus)
|
|
1205
|
-
this.reorderStatus.textContent =
|
|
1214
|
+
this.reorderStatus.textContent = this.localizedMessage("paste-failed-label", "Paste failed.");
|
|
1206
1215
|
this.dispatchEvent(new CustomEvent("spui-cells-edit-error", { detail: { message, edits }, bubbles: true, composed: true }));
|
|
1207
1216
|
}
|
|
1208
1217
|
}
|
|
@@ -191,7 +191,7 @@ export function defineDatePicker() {
|
|
|
191
191
|
control.append(input, calendarButton);
|
|
192
192
|
shadow.replaceChildren(document.createElement("style"), label, control, calendar);
|
|
193
193
|
const style = shadow.querySelector("style");
|
|
194
|
-
style.textContent = `${base}:host{position:relative;display:grid;gap:var(--spui-control-gap,6px);min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}.control{display:flex;position:relative;min-width:0}.control input{box-sizing:border-box;width:100%;min-width:0;min-height:var(--spui-control-height,36px);padding-inline:var(--spui-control-padding-inline,12px) 42px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,var(--colorNeutralStroke1,#8a8886))));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,var(--colorNeutralBackground1,#fff))));box-shadow:var(--spui-control-shadow,none);color:inherit;font:inherit}.control input:focus-visible
|
|
194
|
+
style.textContent = `${base}:host{position:relative;display:grid;gap:var(--spui-control-gap,6px);min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font:inherit}.control{display:flex;position:relative;min-width:0}.control input{box-sizing:border-box;width:100%;min-width:0;min-height:var(--spui-control-height,36px);padding-inline:var(--spui-control-padding-inline,12px) 42px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,var(--colorNeutralStroke1,#8a8886))));border-radius:var(--spui-control-radius,4px);background:var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,var(--colorNeutralBackground1,#fff))));box-shadow:var(--spui-control-shadow,none);color:inherit;font:inherit}.control input:focus-visible{border-width:2px;border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline:0;box-shadow:none}.calendar-button:focus-visible,.calendar button:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline-offset:1px}.control input[aria-invalid]:not([aria-invalid=false]){border-color:var(--spui-input-invalid-border,var(--spui-ui-danger,var(--spui-semantic-danger,var(--colorPaletteRedBorderActive,#d13438))))}.control input[aria-invalid]:not([aria-invalid=false]):focus-visible{border-color:var(--spui-input-invalid-border,var(--spui-ui-danger,var(--spui-semantic-danger,var(--colorPaletteRedBorderActive,#d13438))))}.calendar-button{position:absolute;inset-block:2px;inset-inline-end:2px;display:grid;place-items:center;width:36px;border:0;border-radius:var(--spui-control-radius,4px);background:transparent;color:var(--spui-ui-muted,var(--colorNeutralForeground2,#616161));cursor:pointer}.calendar-button:hover{background:var(--spui-ui-surface-hover,var(--colorNeutralBackground1Hover,#f5f5f5));color:var(--spui-ui-text,inherit)}label{font-size:14px;font-weight:600;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit))}.calendar{position:absolute;inset-block-start:calc(100% + 4px);inset-inline-start:0;z-index:var(--spui-layer-dropdown,20);width:min(320px,calc(100vw - 24px));padding:12px;border:1px solid var(--spui-ui-stroke,var(--colorNeutralStroke1,#d1d1d1));border-radius:var(--spui-card-radius,8px);background:var(--spui-ui-surface,var(--colorNeutralBackground1,#fff));box-shadow:var(--spui-card-shadow,0 4px 16px #0002);color:var(--spui-ui-text,var(--colorNeutralForeground1,#242424));direction:inherit}.calendar[hidden]{display:none}.calendar-header{display:grid;grid-template-columns:36px 1fr 36px;align-items:center;gap:4px;margin-block-end:8px}.month-label{text-align:center;font-weight:600}.calendar button{font:inherit}.month-nav{display:grid;place-items:center;width:36px;height:36px;border:0;border-radius:var(--spui-control-radius,4px);background:transparent;color:inherit;cursor:pointer}.month-nav:hover{background:var(--spui-ui-surface-hover,#f5f5f5)}.weekdays{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:2px}.days{display:grid;gap:2px}.days>[role=row]{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:2px}.weekday{display:grid;place-items:center;height:32px;color:var(--spui-ui-muted,var(--colorNeutralForeground2,#616161));font-size:12px;font-weight:600}.day{display:grid;place-items:center;min-width:0;aspect-ratio:1;border:0;border-radius:50%;background:transparent;color:inherit;cursor:pointer}.day:hover:not(:disabled){background:var(--spui-ui-surface-hover,var(--colorNeutralBackground1Hover,#f5f5f5))}.day[aria-selected=true]{background:var(--spui-ui-accent,var(--colorBrandBackground,#0f6cbd));color:var(--spui-ui-accent-text,var(--colorNeutralForegroundOnBrand,#fff))}.day[aria-current=date]{outline:1px solid var(--spui-ui-accent,var(--colorBrandForeground1,#0f6cbd));outline-offset:-2px}.day.outside-month{color:var(--spui-ui-muted,var(--colorNeutralForeground3,#a19f9d))}.day:disabled{opacity:.42;cursor:default}.calendar[dir=rtl]{direction:rtl}@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important}}@media(forced-colors:active){.calendar,.control input{border-color:FieldText}.control input:focus-visible{border-color:Highlight;outline:0}.control input[aria-invalid]:not([aria-invalid=false]):focus-visible{border-color:Highlight}.day[aria-selected=true]{outline:2px solid Highlight}.calendar-button,.month-nav,.day{forced-color-adjust:auto}}`;
|
|
195
195
|
style.textContent += `.control input:disabled,.calendar-button:disabled,.month-nav:disabled{cursor:not-allowed;opacity:.5}.calendar-button:disabled:hover,.month-nav:disabled:hover{background:transparent}.day[aria-disabled=true]{opacity:.42;cursor:default}`;
|
|
196
196
|
this.syncInput();
|
|
197
197
|
this.syncInputAttributes();
|
package/dist/elements/dialog.js
CHANGED
|
@@ -364,7 +364,7 @@ export function defineDialog() {
|
|
|
364
364
|
this.closeDialog("backdropClick", event);
|
|
365
365
|
});
|
|
366
366
|
const style = document.createElement("style");
|
|
367
|
-
style.textContent = `${base}:host{display:contents}dialog{position:relative;z-index:2147483647;box-sizing:border-box;width:min(520px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);overflow:auto;padding:0;border:1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1));border-radius:var(--spui-card-radius,12px);background:var(--spui-card-background,var(--spui-ui-surface,#fff));box-shadow:var(--spui-card-shadow,0 16px 48px #0004);color:var(--spui-ui-text,var(--spui-semantic-body-text,#242424))}dialog::backdrop{background:color-mix(in srgb,var(--spui-ui-text,#242424) 42%,transparent);backdrop-filter:blur(2px)}:host([backdrop-appearance=transparent]) dialog::backdrop{background:transparent;backdrop-filter:none}header{display:flex;align-items:start;justify-content:space-between;gap:16px;padding:20px 20px 0}h2{margin:0;font-size:20px;line-height:1.3;font-weight:650}.close{display:inline-grid;place-items:center;flex:none;width:var(--spui-control-height,32px);height:var(--spui-control-height,32px);margin:-5px
|
|
367
|
+
style.textContent = `${base}:host{display:contents}dialog{position:relative;z-index:2147483647;box-sizing:border-box;width:min(520px,calc(100vw - 32px));max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);overflow:auto;padding:0;border:1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1));border-radius:var(--spui-card-radius,12px);background:var(--spui-card-background,var(--spui-ui-surface,#fff));box-shadow:var(--spui-card-shadow,0 16px 48px #0004);color:var(--spui-ui-text,var(--spui-semantic-body-text,#242424))}dialog::backdrop{background:color-mix(in srgb,var(--spui-ui-text,#242424) 42%,transparent);backdrop-filter:blur(2px)}:host([backdrop-appearance=transparent]) dialog::backdrop{background:transparent;backdrop-filter:none}header{display:flex;align-items:start;justify-content:space-between;gap:16px;padding:20px 20px 0}h2{margin:0;font-size:20px;line-height:1.3;font-weight:650}.close{display:inline-grid;place-items:center;flex:none;width:var(--spui-control-height,32px);height:var(--spui-control-height,32px);margin:-5px 0 0;margin-inline-end:-6px;border:0;border-radius:var(--spui-control-radius,6px);background:transparent;color:inherit;font-size:24px;line-height:1;cursor:pointer}.close:hover{background:var(--spui-ui-surface-hover,#f5f5f5)}.close:focus-visible{outline:2px solid var(--spui-focus-ring,#005a9e);outline-offset:2px}.body{padding:16px 20px 20px;line-height:1.5}footer{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px;padding:12px 20px 20px;border-top:1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1))}footer[hidden]{display:none}@media(forced-colors:active){dialog{border-color:CanvasText;box-shadow:none}dialog::backdrop{background:Canvas} .close:focus-visible{outline-color:Highlight}}`;
|
|
368
368
|
const overlayStyle = document.createElement("style");
|
|
369
369
|
overlayStyle.textContent = ".modal-backdrop{position:fixed;inset:0;z-index:2147483000;background:color-mix(in srgb,var(--spui-ui-text,#242424) 42%,transparent);backdrop-filter:blur(2px)}.modal-backdrop[hidden]{display:none}.modal-backdrop slot{position:absolute;inset:0}:host([data-has-custom-backdrop]) .modal-backdrop{background:transparent;backdrop-filter:none}:host([backdrop-appearance=transparent]) .modal-backdrop{background:transparent;backdrop-filter:none}::slotted([slot=backdrop]){position:absolute;inset:0;display:block;background:color-mix(in srgb,var(--spui-ui-text,#242424) 42%,transparent)}::slotted([slot=backdrop][data-appearance=transparent]){background:transparent}";
|
|
370
370
|
const backdrop = document.createElement("div");
|
|
@@ -33,7 +33,7 @@ export function defineFileUpload() {
|
|
|
33
33
|
render() {
|
|
34
34
|
const shadow = this.attachShadow({ mode: "open" });
|
|
35
35
|
const style = document.createElement("style");
|
|
36
|
-
style.textContent = `${base}:host{display:block;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,#242424));font-family:var(--spui-font-family,inherit)}.label{display:block;margin-block-end:6px;font-size:14px;font-weight:600}.drop{box-sizing:border-box;display:grid;place-items:center;gap:6px;min-height:104px;padding:16px;border:1px dashed var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886));border-radius:var(--spui-control-radius,6px);background:var(--spui-ui-surface,var(--spui-semantic-input-background,#fff));text-align:center;transition:border-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),background-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}.drop[data-dragging=true]{border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.hint{color:var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161));font-size:12px}.browse{min-height:32px;padding:4px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,#8a8886));border-radius:var(--spui-control-radius,4px);background:var(--spui-ui-surface,#fff);color:inherit;font:inherit;cursor:pointer}.browse:hover:not(:disabled){background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.browse:focus-visible,.remove:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline-offset:2px}.browse:disabled,.remove:disabled{opacity:.55;cursor:not-allowed}.input{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.files{display:grid;gap:4px;margin:8px 0 0;padding:0;list-style:none}.files:empty{display:none}.file{display:flex;align-items:center;gap:8px;min-width:0;padding:6px 8px;border:1px solid var(--spui-ui-stroke,#d1d1d1);border-radius:var(--spui-control-radius,4px)}.filename{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.size{flex:none;color:var(--spui-ui-muted,#616161);font-size:12px;font-variant-numeric:tabular-nums}.remove{min-width:32px;min-height:32px;border:0;border-radius:var(--spui-control-radius,4px);background:transparent;color:inherit;font:inherit;cursor:pointer}.status{margin-block-start:6px;color:var(--spui-semantic-error-text,var(--spui-ui-danger,#b10e1c));font-size:12px}.status:empty{display:none}:host([data-spui-appearance=glass]) .drop{backdrop-filter:var(--spui-card-backdrop,blur(12px) saturate(1.2))}@media(prefers-reduced-motion:reduce){.drop{transition:none}}@media(forced-colors:active){.drop,.file{border-color:CanvasText;background:Canvas;color:CanvasText}.drop[data-dragging=true]{outline:2px solid Highlight}.browse{border-color:ButtonText;background:ButtonFace;color:ButtonText}}`;
|
|
36
|
+
style.textContent = `${base}:host{display:block;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,#242424));font-family:var(--spui-font-family,inherit)}.label{display:block;margin-block-end:6px;font-size:14px;font-weight:600}.drop{box-sizing:border-box;display:grid;place-items:center;gap:6px;min-height:104px;padding:16px;border:1px dashed var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886));border-radius:var(--spui-control-radius,6px);background:var(--spui-ui-surface,var(--spui-semantic-input-background,#fff));text-align:center;transition:border-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),background-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}.drop[data-dragging=true]{border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.hint{color:var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161));font-size:12px}.browse{min-height:32px;padding:4px 12px;border:1px solid var(--spui-control-border,var(--spui-ui-stroke,#8a8886));border-radius:var(--spui-control-radius,4px);background:var(--spui-ui-surface,#fff);color:inherit;font:inherit;cursor:pointer}.browse:hover:not(:disabled){background:var(--spui-ui-surface-hover,var(--spui-ui-canvas,#f5f5f5))}.browse:focus-visible,.remove:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline-offset:2px}.browse:disabled,.remove:disabled{opacity:.55;cursor:not-allowed}.input{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.files{display:grid;gap:4px;margin:8px 0 0;padding:0;list-style:none}.files:empty{display:none}.file{display:flex;align-items:center;gap:8px;min-width:0;padding:6px 8px;border:1px solid var(--spui-ui-stroke,#d1d1d1);border-radius:var(--spui-control-radius,4px)}.filename{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.size{flex:none;color:var(--spui-ui-muted,#616161);font-size:12px;font-variant-numeric:tabular-nums}.remove{min-width:32px;min-height:32px;border:0;border-radius:var(--spui-control-radius,4px);background:transparent;color:inherit;font:inherit;cursor:pointer}.status{margin-block-start:6px;color:var(--spui-semantic-error-text,var(--spui-ui-danger,#b10e1c));font-size:12px}.status:empty{display:none}:host([data-spui-appearance=glass]) .drop,:host-context([data-spui-appearance=glass]) .drop{backdrop-filter:var(--spui-card-backdrop,blur(12px) saturate(1.2))}@media(prefers-reduced-motion:reduce){.drop{transition:none}}@media(forced-colors:active){.drop,.file{border-color:CanvasText;background:Canvas;color:CanvasText}.drop[data-dragging=true]{outline:2px solid Highlight}.browse{border-color:ButtonText;background:ButtonFace;color:ButtonText}}`;
|
|
37
37
|
const label = document.createElement("label");
|
|
38
38
|
label.className = "label";
|
|
39
39
|
label.part.add("label");
|
|
@@ -17,6 +17,16 @@ export type FloatingModifiers = {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
export type FloatingAnchorRect = Pick<DOMRectReadOnly, "left" | "top" | "right" | "bottom" | "width" | "height">;
|
|
20
|
+
export type FloatingBoundary = Element | {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
} | readonly Element[] | "clippingParents" | "scrollParent" | "window" | null;
|
|
26
|
+
export declare function getFloatingBoundary(boundary: FloatingBoundary | undefined, context: Element, viewport?: {
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
}): Pick<DOMRectReadOnly, "left" | "top" | "right" | "bottom"> | undefined;
|
|
20
30
|
export declare function getFloatingPosition(anchor: FloatingAnchorRect, surface: Pick<DOMRectReadOnly, "width" | "height">, placement: FloatingPlacement, direction: "ltr" | "rtl", gap?: number, viewport?: {
|
|
21
31
|
width: number;
|
|
22
32
|
height: number;
|
|
@@ -1,3 +1,56 @@
|
|
|
1
|
+
export function getFloatingBoundary(boundary, context, viewport = { width: innerWidth, height: innerHeight }) {
|
|
2
|
+
if (boundary === undefined || boundary === null || boundary === "window")
|
|
3
|
+
return undefined;
|
|
4
|
+
const rectEdges = (rect) => {
|
|
5
|
+
const left = rect.left ?? rect.x ?? 0;
|
|
6
|
+
const top = rect.top ?? rect.y ?? 0;
|
|
7
|
+
return { left, top, right: left + rect.width, bottom: top + rect.height };
|
|
8
|
+
};
|
|
9
|
+
const isElement = (value) => Boolean(value && typeof value === "object" && value.nodeType === 1 && typeof value.getBoundingClientRect === "function");
|
|
10
|
+
if (Array.isArray(boundary)) {
|
|
11
|
+
const rects = boundary.map(element => rectEdges(element.getBoundingClientRect()));
|
|
12
|
+
if (!rects.length)
|
|
13
|
+
return undefined;
|
|
14
|
+
const left = Math.max(...rects.map(rect => rect.left));
|
|
15
|
+
const top = Math.max(...rects.map(rect => rect.top));
|
|
16
|
+
return { left, top, right: Math.max(left, Math.min(...rects.map(rect => rect.right))), bottom: Math.max(top, Math.min(...rects.map(rect => rect.bottom))) };
|
|
17
|
+
}
|
|
18
|
+
if (isElement(boundary))
|
|
19
|
+
return rectEdges(boundary.getBoundingClientRect());
|
|
20
|
+
if (typeof boundary === "object" && "width" in boundary && "height" in boundary)
|
|
21
|
+
return rectEdges(boundary);
|
|
22
|
+
if (boundary !== "clippingParents" && boundary !== "scrollParent")
|
|
23
|
+
return undefined;
|
|
24
|
+
const bounds = { left: 0, top: 0, right: viewport.width, bottom: viewport.height };
|
|
25
|
+
const view = context.ownerDocument.defaultView;
|
|
26
|
+
const parent = (current) => current.parentElement ?? (current.getRootNode() instanceof ShadowRoot ? current.getRootNode().host : null);
|
|
27
|
+
for (let current = parent(context); current; current = parent(current)) {
|
|
28
|
+
const style = view?.getComputedStyle(current);
|
|
29
|
+
if (!style)
|
|
30
|
+
continue;
|
|
31
|
+
const clipsX = /^(auto|scroll|hidden|clip|overlay)$/.test(style.overflowX);
|
|
32
|
+
const clipsY = /^(auto|scroll|hidden|clip|overlay)$/.test(style.overflowY);
|
|
33
|
+
const scrolls = /^(auto|scroll|hidden|overlay)$/.test(style.overflowX) || /^(auto|scroll|hidden|overlay)$/.test(style.overflowY);
|
|
34
|
+
if (boundary === "scrollParent" && !scrolls)
|
|
35
|
+
continue;
|
|
36
|
+
if (!clipsX && !clipsY)
|
|
37
|
+
continue;
|
|
38
|
+
const rect = current.getBoundingClientRect();
|
|
39
|
+
const left = rect.left + current.clientLeft;
|
|
40
|
+
const top = rect.top + current.clientTop;
|
|
41
|
+
if (boundary === "scrollParent")
|
|
42
|
+
return { left, top, right: left + current.clientWidth, bottom: top + current.clientHeight };
|
|
43
|
+
if (clipsX) {
|
|
44
|
+
bounds.left = Math.max(bounds.left, left);
|
|
45
|
+
bounds.right = Math.min(bounds.right, left + current.clientWidth);
|
|
46
|
+
}
|
|
47
|
+
if (clipsY) {
|
|
48
|
+
bounds.top = Math.max(bounds.top, top);
|
|
49
|
+
bounds.bottom = Math.min(bounds.bottom, top + current.clientHeight);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { left: bounds.left, top: bounds.top, right: Math.max(bounds.left, bounds.right), bottom: Math.max(bounds.top, bounds.bottom) };
|
|
53
|
+
}
|
|
1
54
|
export function getFloatingPosition(anchor, surface, placement, direction, gap = 8, viewport = { width: innerWidth, height: innerHeight }, align = "center", fallbackPlacements = [], pinned = false, flipBoundary, overflowBoundary, modifiers = {}) {
|
|
2
55
|
const viewportBoundary = { left: 0, top: 0, right: viewport.width, bottom: viewport.height };
|
|
3
56
|
const flipBounds = flipBoundary ?? viewportBoundary;
|
package/dist/elements/info.js
CHANGED
|
@@ -29,7 +29,7 @@ export function defineInfoButton() {
|
|
|
29
29
|
render() {
|
|
30
30
|
const shadow = this.attachShadow({ mode: "open" });
|
|
31
31
|
const style = document.createElement("style");
|
|
32
|
-
style.textContent = `:host{display:inline-flex;vertical-align:middle;line-height:1}:host([hidden]){display:none}button{display:inline-grid;place-items:center;box-sizing:border-box;width:var(--spui-info-button-size,20px);height:var(--spui-info-button-size,20px);padding:2px;border:1px solid transparent;border-radius:50%;background:transparent;color:var(--spui-info-button-color,var(--spui-ui-muted,var(--spui-semantic-body-text,#484644)));cursor:pointer;font:inherit}button:hover:not(:disabled){background:var(--spui-info-button-hover,var(--spui-ui-surface-hover,#f3f2f1));color:var(--spui-ui-accent,var(--spui-semantic-link,#0f6cbd))}button:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#005a9e));outline-offset:2px}button:disabled{opacity:.55;cursor:not-allowed}svg{width:calc(var(--spui-info-button-size,20px) * .8);height:calc(var(--spui-info-button-size,20px) * .8);fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}:host([size=small]){--spui-info-button-size:16px}:host([size=large]){--spui-info-button-size:24px}:host([data-spui-appearance=glass]) button{backdrop-filter:blur(8px)}@media(forced-colors:active){button{border-color:ButtonText;color:ButtonText}button:focus-visible{outline-color:Highlight}}`;
|
|
32
|
+
style.textContent = `:host{display:inline-flex;vertical-align:middle;line-height:1}:host([hidden]){display:none}button{display:inline-grid;place-items:center;box-sizing:border-box;width:var(--spui-info-button-size,20px);height:var(--spui-info-button-size,20px);padding:2px;border:1px solid transparent;border-radius:50%;background:transparent;color:var(--spui-info-button-color,var(--spui-ui-muted,var(--spui-semantic-body-text,#484644)));cursor:pointer;font:inherit}button:hover:not(:disabled){background:var(--spui-info-button-hover,var(--spui-ui-surface-hover,#f3f2f1));color:var(--spui-ui-accent,var(--spui-semantic-link,#0f6cbd))}button:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#005a9e));outline-offset:2px}button:disabled{opacity:.55;cursor:not-allowed}svg{width:calc(var(--spui-info-button-size,20px) * .8);height:calc(var(--spui-info-button-size,20px) * .8);fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}:host([size=small]){--spui-info-button-size:16px}:host([size=large]){--spui-info-button-size:24px}:host([data-spui-appearance=glass]) button,:host-context([data-spui-appearance=glass]) button{backdrop-filter:blur(8px)}@media(forced-colors:active){button{border-color:ButtonText;color:ButtonText}button:focus-visible{outline-color:Highlight}}`;
|
|
33
33
|
const popover = document.createElement("spui-popover");
|
|
34
34
|
this.popoverElement = popover;
|
|
35
35
|
const trigger = document.createElement("button");
|
package/dist/elements/input.js
CHANGED
|
@@ -209,8 +209,8 @@ export function defineInput() {
|
|
|
209
209
|
render() {
|
|
210
210
|
const shadow = this.attachShadow({ mode: "open" });
|
|
211
211
|
const style = document.createElement("style");
|
|
212
|
-
style.textContent = `${base}:host{display:inline-block;min-width:0;vertical-align:middle}.control{box-sizing:border-box;display:flex;align-items:center;gap:var(--spui-input-content-gap,8px);min-width:0;width:100%;border:1px solid var(--spui-input-border,var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886))));border-radius:var(--spui-input-radius,var(--spui-control-radius,4px));background:var(--spui-input-background,var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff))));box-shadow:var(--spui-input-shadow,var(--spui-control-shadow,none));color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font-family:var(--spui-font-family,inherit);font-size:var(--fontSizeBase200,14px);transition:border-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),box-shadow var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}.control:focus-within{border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));box-shadow:
|
|
213
|
-
style.textContent += `slot[name=input]{display:contents}slot[name=input]::slotted(input){box-sizing:border-box;flex:1;min-width:0;width:100%;height:100%;padding-inline:var(--spui-input-padding-inline,var(--spui-control-padding-inline,12px));border:0;outline:0;background:transparent;color:inherit;font:var(--spui-input-font,var(--spui-font-family,inherit));font-size:inherit}slot[name=input]::slotted(input:disabled){cursor:not-allowed;opacity:.55}`;
|
|
212
|
+
style.textContent = `${base}:host{display:inline-block;min-width:0;vertical-align:middle}.control{box-sizing:border-box;display:flex;align-items:center;gap:var(--spui-input-content-gap,8px);min-width:0;width:100%;border:1px solid var(--spui-input-border,var(--spui-control-border,var(--spui-ui-stroke,var(--spui-semantic-input-border,#8a8886))));border-radius:var(--spui-input-radius,var(--spui-control-radius,4px));background:var(--spui-input-background,var(--spui-control-background,var(--spui-ui-surface,var(--spui-semantic-input-background,#fff))));box-shadow:var(--spui-input-shadow,var(--spui-control-shadow,none));color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font-family:var(--spui-font-family,inherit);font-size:var(--fontSizeBase200,14px);transition:border-color var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1)),box-shadow var(--spui-motion-duration-fast,120ms) var(--spui-motion-easing-standard,cubic-bezier(.2,0,0,1))}.control:focus-within{border-color:var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));box-shadow:none}.control:has(input[aria-invalid]:not([aria-invalid=false])){border-color:var(--spui-input-invalid-border,var(--spui-ui-danger,var(--colorPaletteRedBorder2,#c50f1f)))}.control[data-size=small]{min-height:24px;font-size:var(--fontSizeBase100,12px)}.control[data-size=medium]{min-height:32px}.control[data-size=large]{min-height:40px;font-size:var(--fontSizeBase200,14px)}.control[data-appearance=underline]{border-width:0 0 1px;border-radius:0;box-shadow:none}.control[data-appearance=underline]:focus-within{border-width:0 0 1px}.control[data-appearance=filled-darker],.control[data-appearance=filled-darker-shadow]{background:var(--spui-input-filled-darker,var(--spui-ui-surface-hover,var(--colorNeutralBackground3,#f0f0f0)));border-color:transparent}.control[data-appearance=filled-lighter],.control[data-appearance=filled-lighter-shadow]{background:var(--spui-input-filled-lighter,var(--spui-ui-canvas,var(--colorNeutralBackground1,#fafafa)));border-color:transparent}.control[data-appearance=filled-darker-shadow],.control[data-appearance=filled-lighter-shadow]{box-shadow:var(--spui-input-filled-shadow,var(--shadow2,0 1px 2px rgb(0 0 0 / 20%)))}input{box-sizing:border-box;flex:1;min-width:0;width:100%;height:100%;padding-inline:var(--spui-input-padding-inline,var(--spui-control-padding-inline,12px));border:0!important;outline:0!important;box-shadow:none!important;background:transparent;color:inherit;font:var(--spui-input-font,var(--spui-font-family,inherit));font-size:inherit}input:focus-visible{outline:0!important;outline-offset:0;box-shadow:none!important}input::placeholder{color:var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161));opacity:1}input:disabled{cursor:not-allowed;opacity:.55}.control:has(input:disabled){opacity:.65}slot[name=before],slot[name=after]{display:inline-flex;align-items:center;flex:none;color:var(--spui-input-content-color,var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161)))}slot[name=before]{padding-inline-start:12px}slot[name=after]{padding-inline-end:12px}:host([data-spui-appearance=glass]) .control,:host-context([data-spui-appearance=glass]) .control{backdrop-filter:blur(12px) saturate(1.2)}@media(prefers-reduced-motion:reduce){.control{transition:none}}@media(forced-colors:active){.control{border-color:FieldText;background:Field;color:FieldText}.control:focus-within{border:1px solid Highlight;outline:0;box-shadow:none}.control:has(input[aria-invalid]:not([aria-invalid=false])){border-color:CanvasText}.control:has(input[aria-invalid]:not([aria-invalid=false])):focus-within{border-color:Highlight}.control[data-appearance=underline]:focus-within{border-width:0 0 1px}input::placeholder{color:GrayText}}`;
|
|
213
|
+
style.textContent += `slot[name=input]{display:contents}slot[name=input]::slotted(input){box-sizing:border-box;flex:1;min-width:0;width:100%;height:100%;padding-inline:var(--spui-input-padding-inline,var(--spui-control-padding-inline,12px));border:0!important;outline:0!important;box-shadow:none!important;background:transparent;color:inherit;font:var(--spui-input-font,var(--spui-font-family,inherit));font-size:inherit}slot[name=input]::slotted(input:focus-visible){border:0!important;outline:0!important;outline-offset:0;box-shadow:none!important}slot[name=input]::slotted(input:disabled){cursor:not-allowed;opacity:.55}`;
|
|
214
214
|
style.textContent += `input[type=checkbox],input[type=radio],slot[name=input]::slotted(input[type=checkbox]),slot[name=input]::slotted(input[type=radio]){box-sizing:border-box;flex:none;width:16px;height:16px;padding:0}`;
|
|
215
215
|
const control = document.createElement("div");
|
|
216
216
|
control.className = "control";
|
package/dist/elements/link.js
CHANGED
|
@@ -61,7 +61,7 @@ export function defineLink() {
|
|
|
61
61
|
render() {
|
|
62
62
|
const shadow = this.attachShadow({ mode: "open" });
|
|
63
63
|
const style = document.createElement("style");
|
|
64
|
-
style.textContent = `${base}:host{display:inline;color:var(--spui-link-color,var(--spui-semantic-link,var(--colorBrandForeground1,#115ea3)))}a,button,span{box-sizing:border-box;background:transparent;border:0;color:inherit;font:inherit;text-align:inherit;text-decoration:none;cursor:pointer;padding:0;margin:0}a,span{display:inline}button{display:inline}a:visited{color:var(--spui-link-visited,var(--spui-semantic-link-visited,var(--colorBrandForeground2,#4f52b2)))
|
|
64
|
+
style.textContent = `${base}:host{display:inline;color:var(--spui-link-color,var(--spui-semantic-link,var(--colorBrandForeground1,#115ea3)))}a,button,span{box-sizing:border-box;background:transparent;border:0;color:inherit;font:inherit;text-align:inherit;text-decoration:none;cursor:pointer;padding:0;margin:0}a,span{display:inline}button{display:inline}a:visited{color:var(--spui-link-visited,var(--spui-semantic-link-visited,var(--colorBrandForeground2,#4f52b2)))}a:hover,button:hover,span:hover{text-decoration:underline}a:focus-visible,button:focus-visible,span:focus-visible{outline:2px solid var(--spui-focus-ring,var(--spui-semantic-focus-border,#005a9e));outline-offset:2px} [aria-disabled=true]{color:var(--spui-ui-foreground-disabled,var(--spui-ui-muted,#777));cursor:not-allowed;text-decoration:none}[aria-disabled=true]:hover,[aria-disabled=true]:active{text-decoration:none}@media(forced-colors:active){[aria-disabled=true]{color:GrayText}}:host([underline=always]) a,:host([underline=always]) button,:host([underline=always]) span{text-decoration:underline;text-decoration-thickness:from-font;text-underline-offset:2px}:host([underline=hover]) a,:host([underline=hover]) button,:host([underline=hover]) span{text-decoration:none}:host([underline=hover]) a:hover,:host([underline=hover]) button:hover,:host([underline=hover]) span:hover,:host([underline=hover]) a:focus-visible,:host([underline=hover]) button:focus-visible,:host([underline=hover]) span:focus-visible,:host([inline]) a,:host([inline]) button,:host([inline]) span{text-decoration:underline}:host([appearance=subtle]){color:var(--spui-ui-text,var(--spui-semantic-body-text,#323130))}:host([appearance=subtle]) a:visited{color:inherit}`;
|
|
65
65
|
shadow.append(style);
|
|
66
66
|
this.renderRoot(this.getAttribute("as") || (this.getAttribute("href") ? "a" : "button"));
|
|
67
67
|
this.addEventListener("click", event => { if (this.isDisabled()) {
|
|
@@ -66,8 +66,10 @@ function definePart(tag, content, css, observed = []) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
for (const node of record.removedNodes)
|
|
69
|
-
if (node instanceof HTMLElement && node.localName === "spui-message-bar" && !node.hasAttribute("data-spui-exiting"))
|
|
69
|
+
if (node instanceof HTMLElement && node.localName === "spui-message-bar" && !node.hasAttribute("data-spui-exiting")) {
|
|
70
|
+
this.resizeObserver?.unobserve(node);
|
|
70
71
|
this.animateExit(node);
|
|
72
|
+
}
|
|
71
73
|
}
|
|
72
74
|
});
|
|
73
75
|
this.childObserver.observe(this, { childList: true });
|
|
@@ -78,12 +80,32 @@ function definePart(tag, content, css, observed = []) {
|
|
|
78
80
|
animateExit(bar) {
|
|
79
81
|
const view = this.ownerDocument.defaultView;
|
|
80
82
|
const rect = this.childRects.get(bar);
|
|
81
|
-
if (!view || !rect || this.getAttribute("animate") === "none")
|
|
83
|
+
if (!view || !rect || this.getAttribute("animate") === "none" || view.matchMedia("(prefers-reduced-motion: reduce)").matches)
|
|
82
84
|
return;
|
|
83
85
|
const groupRect = this.getBoundingClientRect();
|
|
86
|
+
for (const sibling of this.querySelectorAll(":scope > spui-message-bar:not([data-spui-exiting])")) {
|
|
87
|
+
const previous = this.childRects.get(sibling);
|
|
88
|
+
const current = sibling.getBoundingClientRect();
|
|
89
|
+
this.childRects.set(sibling, current);
|
|
90
|
+
const offset = previous ? previous.top - current.top : 0;
|
|
91
|
+
if (Math.abs(offset) < 1)
|
|
92
|
+
continue;
|
|
93
|
+
sibling.style.setProperty("--spui-message-shift", `${offset}px`);
|
|
94
|
+
sibling.setAttribute("data-spui-shifting", "");
|
|
95
|
+
const clearShift = () => {
|
|
96
|
+
sibling.removeAttribute("data-spui-shifting");
|
|
97
|
+
sibling.style.removeProperty("--spui-message-shift");
|
|
98
|
+
sibling.removeEventListener("animationend", clearShift);
|
|
99
|
+
sibling.removeEventListener("animationcancel", clearShift);
|
|
100
|
+
};
|
|
101
|
+
sibling.addEventListener("animationend", clearShift);
|
|
102
|
+
sibling.addEventListener("animationcancel", clearShift);
|
|
103
|
+
}
|
|
84
104
|
const clone = bar.cloneNode(true);
|
|
85
105
|
clone.setAttribute("data-spui-exiting", "");
|
|
86
106
|
clone.setAttribute("aria-hidden", "true");
|
|
107
|
+
clone.removeAttribute("data-spui-shifting");
|
|
108
|
+
clone.style.removeProperty("--spui-message-shift");
|
|
87
109
|
clone.inert = true;
|
|
88
110
|
clone.removeAttribute("id");
|
|
89
111
|
clone.querySelectorAll("[id], [data-testid]").forEach(node => { node.removeAttribute("id"); node.removeAttribute("data-testid"); });
|
|
@@ -97,9 +119,15 @@ function definePart(tag, content, css, observed = []) {
|
|
|
97
119
|
pointerEvents: "none",
|
|
98
120
|
zIndex: "1",
|
|
99
121
|
});
|
|
100
|
-
|
|
122
|
+
const removeClone = () => {
|
|
123
|
+
clone.removeEventListener("animationend", removeClone);
|
|
124
|
+
clone.removeEventListener("animationcancel", removeClone);
|
|
125
|
+
clone.remove();
|
|
126
|
+
};
|
|
127
|
+
clone.addEventListener("animationend", removeClone);
|
|
128
|
+
clone.addEventListener("animationcancel", removeClone);
|
|
101
129
|
this.append(clone);
|
|
102
|
-
view.setTimeout(
|
|
130
|
+
view.setTimeout(removeClone, 300);
|
|
103
131
|
}
|
|
104
132
|
}
|
|
105
133
|
customElements.define(tag, SpuiMessageBarPart);
|
|
@@ -114,7 +142,7 @@ export function defineMessageBarTitle() {
|
|
|
114
142
|
definePart("spui-message-bar-title", "<slot></slot>", ":host{display:inline;font-weight:600}");
|
|
115
143
|
}
|
|
116
144
|
export function defineMessageBarGroup() {
|
|
117
|
-
definePart("spui-message-bar-group", "<slot></slot>", ":host{position:relative;display:grid;gap:8px}:host([data-animate=both]) ::slotted(spui-message-bar:not([data-spui-exiting])){animation:spui-message-enter 160ms cubic-bezier(.2,0,0,1) both}::slotted(spui-message-bar[data-spui-exiting]){animation:spui-message-exit 250ms ease-in both}@keyframes spui-message-enter{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes spui-message-exit{to{opacity:0}}@media(prefers-reduced-motion:reduce){:host([data-animate=both]) ::slotted(spui-message-bar:not([data-spui-exiting])),::slotted(spui-message-bar[data-spui-exiting]){animation:none}}", ["animate"]);
|
|
145
|
+
definePart("spui-message-bar-group", "<slot></slot>", ":host{position:relative;display:grid;gap:8px}:host([data-animate=both]) ::slotted(spui-message-bar:not([data-spui-exiting])){animation:spui-message-enter 160ms cubic-bezier(.2,0,0,1) both}::slotted(spui-message-bar[data-spui-exiting]){animation:spui-message-exit 250ms ease-in both}:host([data-animate]) ::slotted(spui-message-bar[data-spui-shifting]){animation:spui-message-shift 180ms cubic-bezier(.2,0,0,1) both}@keyframes spui-message-enter{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes spui-message-exit{to{opacity:0}}@keyframes spui-message-shift{from{transform:translateY(var(--spui-message-shift,0px))}to{transform:translateY(0)}}@media(prefers-reduced-motion:reduce){:host([data-animate=both]) ::slotted(spui-message-bar:not([data-spui-exiting])),::slotted(spui-message-bar[data-spui-exiting]),:host([data-animate]) ::slotted(spui-message-bar[data-spui-shifting]){animation:none}}", ["animate"]);
|
|
118
146
|
}
|
|
119
147
|
export function defineMessageBar() {
|
|
120
148
|
if (customElements.get("spui-message-bar"))
|
package/dist/elements/nav.js
CHANGED
|
@@ -20,7 +20,7 @@ export function defineNav() {
|
|
|
20
20
|
if (customElements.get("spui-nav"))
|
|
21
21
|
return;
|
|
22
22
|
class SpuiNav extends HTMLElement {
|
|
23
|
-
static observedAttributes = ["label", "aria-label", "density", "multiple", "tabbable", "open", "open-label", "close-label", "collapsible", "collapsed", "expand-label", "collapse-label"];
|
|
23
|
+
static observedAttributes = ["label", "aria-label", "density", "multiple", "tabbable", "open", "open-label", "close-label", "collapsible", "collapsed", "full-width", "expand-label", "collapse-label"];
|
|
24
24
|
observer;
|
|
25
25
|
events;
|
|
26
26
|
breakpoint;
|
|
@@ -46,6 +46,8 @@ export function defineNav() {
|
|
|
46
46
|
get defaultCollapsed() { return this.collapsed; }
|
|
47
47
|
set defaultCollapsed(value) { if (!this.collapsedControlled)
|
|
48
48
|
this.setCollapsed(Boolean(value)); }
|
|
49
|
+
get fullWidth() { return this.hasAttribute("full-width"); }
|
|
50
|
+
set fullWidth(value) { this.toggleAttribute("full-width", Boolean(value)); }
|
|
49
51
|
connectedCallback() {
|
|
50
52
|
if (!this.shadowRoot)
|
|
51
53
|
this.render();
|
|
@@ -432,6 +434,7 @@ export function defineNav() {
|
|
|
432
434
|
const style = document.createElement("style");
|
|
433
435
|
style.textContent = `${base}
|
|
434
436
|
:host{display:block;width:var(--spui-nav-width,260px);max-width:100%;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,#242424));font:inherit}:host([data-collapsed]){width:var(--spui-nav-collapsed-width,64px)}
|
|
437
|
+
@media(min-width:641px){:host([full-width]:not([data-collapsed])){width:100%}}
|
|
435
438
|
nav{display:grid;grid-template-columns:minmax(0,1fr);gap:2px;width:100%;min-width:0;font-family:var(--spui-font-family,inherit);font-size:var(--spui-nav-font-size,14px);color:inherit}nav[hidden]{display:none}nav slot{min-width:0}
|
|
436
439
|
:host([density=small]) nav{--spui-nav-item-block:5px;--spui-nav-font-size:13px}
|
|
437
440
|
:host([density=large]) nav{--spui-nav-item-block:10px;--spui-nav-font-size:15px}
|
|
@@ -4,6 +4,7 @@ export type OverflowState = {
|
|
|
4
4
|
groupVisibility: Record<string, "visible" | "hidden" | "overflow">;
|
|
5
5
|
};
|
|
6
6
|
export type OverflowAxis = "horizontal" | "vertical";
|
|
7
|
+
export type OverflowDensity = "comfortable" | "compact";
|
|
7
8
|
export declare function defineOverflowItem(): void;
|
|
8
9
|
export declare function defineOverflowDivider(): void;
|
|
9
10
|
export declare function defineOverflow(): void;
|
|
@@ -34,7 +34,7 @@ export function defineOverflow() {
|
|
|
34
34
|
defineOverflowItem();
|
|
35
35
|
defineOverflowDivider();
|
|
36
36
|
class SpuiOverflow extends HTMLElement {
|
|
37
|
-
static observedAttributes = ["aria-label", "minimum-visible", "overflow-direction", "overflow-axis", "has-hidden-items", "padding"];
|
|
37
|
+
static observedAttributes = ["aria-label", "minimum-visible", "overflow-direction", "overflow-axis", "has-hidden-items", "padding", "density"];
|
|
38
38
|
itemSlot;
|
|
39
39
|
triggerSlot;
|
|
40
40
|
row;
|
|
@@ -84,7 +84,7 @@ export function defineOverflow() {
|
|
|
84
84
|
render() {
|
|
85
85
|
const shadow = this.attachShadow({ mode: "open" });
|
|
86
86
|
const style = document.createElement("style");
|
|
87
|
-
style.textContent = `${base}:host{display:block;min-width:0;max-width:100%}.row{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--spui-overflow-gap,var(--spui-toolbar-gap,6px));min-width:0;max-width:100%;overflow:hidden}.row:dir(rtl){direction:rtl}:host([overflow-axis=vertical]) .row{height:100%;flex-direction:column;align-items:stretch}:host([overflow-axis=vertical]) ::slotted([slot=overflow-trigger]){margin-inline-start:0;margin-block-start:auto;align-self:flex-end}::slotted([slot=overflow-trigger]){display:inline-flex;flex:none;margin-inline-start:auto}::slotted([slot=overflow-trigger][hidden]){display:none!important}::slotted(spui-overflow-divider[hidden]){display:none!important}@media(forced-colors:active){.row{forced-color-adjust:auto}}`;
|
|
87
|
+
style.textContent = `${base}:host{display:block;min-width:0;max-width:100%}:host([density=compact]){--spui-control-height:28px;--spui-control-padding-inline:10px;--spui-overflow-gap:4px}.row{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--spui-overflow-gap,var(--spui-toolbar-gap,6px));min-width:0;max-width:100%;overflow:hidden}.row:dir(rtl){direction:rtl}:host([overflow-axis=vertical]) .row{height:100%;flex-direction:column;align-items:stretch}:host([overflow-axis=vertical]) ::slotted([slot=overflow-trigger]){margin-inline-start:0;margin-block-start:auto;align-self:flex-end}::slotted([slot=overflow-trigger]){display:inline-flex;flex:none;margin-inline-start:auto}::slotted([slot=overflow-trigger][hidden]){display:none!important}::slotted(spui-overflow-divider[hidden]){display:none!important}@media(pointer:coarse){:host([density=compact]){--spui-control-height:max(44px,var(--spui-touch-target-min,44px))}}@media(forced-colors:active){.row{forced-color-adjust:auto}}`;
|
|
88
88
|
this.row = document.createElement("div");
|
|
89
89
|
this.row.className = "row";
|
|
90
90
|
this.row.setAttribute("part", "control");
|
package/dist/elements/popover.js
CHANGED
|
@@ -289,7 +289,7 @@ export function definePopover() {
|
|
|
289
289
|
render() {
|
|
290
290
|
const shadow = this.attachShadow({ mode: "open" });
|
|
291
291
|
const style = document.createElement("style");
|
|
292
|
-
style.textContent = `${base}:host{display:contents}.trigger{display:contents}.surface{position:fixed;inset:auto;margin:0;z-index:var(--spui-layer-popover,10000);box-sizing:border-box;width:max-content;max-width:var(--spui-popover-max-width,min(360px,calc(100vw - 16px)));max-height:var(--spui-popover-max-height,min(70vh,calc(100dvh - 24px)));overflow:auto;padding:16px;border:1px solid var(--spui-popover-border,var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1)));border-radius:var(--spui-popover-radius,var(--spui-card-radius,8px));background:var(--spui-popover-background,var(--spui-ui-surface,var(--colorNeutralBackground1,#fff)));color:var(--spui-popover-color,var(--spui-ui-text,var(--colorNeutralForeground1,#242424)));box-shadow:var(--spui-popover-shadow,0 8px 24px rgb(0 0 0 / 18%));font-family:var(--spui-font-family,inherit);font-size:14px;line-height:1.45;opacity:1;transform:scale(1);transform-origin:center;transition:opacity var(--spui-motion-duration-normal,140ms) cubic-bezier(.16,1,.3,1),transform var(--spui-motion-duration-normal,140ms) cubic-bezier(.16,1,.3,1)}@starting-style{.surface:popover-open{opacity:0;transform:scale(.97)}}.surface:not(:popover-open){display:none}.surface[hidden]{display:none}h2{margin:0 0 8px;font:600 16px/1.35 var(--spui-font-family,inherit)}h2:empty{display:none}slot[name=trigger]{display:contents}slot[name=title]:not(:defined){display:none}:host([data-spui-appearance=glass]) .surface{backdrop-filter:blur(18px) saturate(1.35)}:host([appearance=brand]){--spui-popover-background:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4));--spui-popover-color:var(--spui-ui-accent-text,var(--spui-semantic-primary-button-text,#fff));--spui-popover-border:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4))}:host([appearance=inverted]){--spui-popover-background:var(--spui-ui-text,var(--spui-semantic-body-text,#242424));--spui-popover-color:var(--spui-ui-surface,var(--spui-semantic-body-background,#fff));--spui-popover-border:var(--spui-ui-text,var(--spui-semantic-body-text,#242424))}:host([size=small]) .surface{padding:8px;font-size:12px}:host([size=large]) .surface{padding:20px;font-size:16px}@media(prefers-reduced-motion:reduce){.surface{transition:none}}@media(forced-colors:active){.surface{border-color:CanvasText;box-shadow:none}.surface:popover-open{outline:1px solid CanvasText}}`;
|
|
292
|
+
style.textContent = `${base}:host{display:contents}.trigger{display:contents}.surface{position:fixed;inset:auto;margin:0;z-index:var(--spui-layer-popover,10000);box-sizing:border-box;width:max-content;max-width:var(--spui-popover-max-width,min(360px,calc(100vw - 16px)));max-height:var(--spui-popover-max-height,min(70vh,calc(100dvh - 24px)));overflow:auto;padding:16px;border:1px solid var(--spui-popover-border,var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1)));border-radius:var(--spui-popover-radius,var(--spui-card-radius,8px));background:var(--spui-popover-background,var(--spui-ui-surface,var(--colorNeutralBackground1,#fff)));color:var(--spui-popover-color,var(--spui-ui-text,var(--colorNeutralForeground1,#242424)));box-shadow:var(--spui-popover-shadow,0 8px 24px rgb(0 0 0 / 18%));font-family:var(--spui-font-family,inherit);font-size:14px;line-height:1.45;opacity:1;transform:scale(1);transform-origin:center;transition:opacity var(--spui-motion-duration-normal,140ms) cubic-bezier(.16,1,.3,1),transform var(--spui-motion-duration-normal,140ms) cubic-bezier(.16,1,.3,1)}@starting-style{.surface:popover-open{opacity:0;transform:scale(.97)}}.surface:not(:popover-open){display:none}.surface[hidden]{display:none}h2{margin:0 0 8px;font:600 16px/1.35 var(--spui-font-family,inherit)}h2:empty{display:none}slot[name=trigger]{display:contents}slot[name=title]:not(:defined){display:none}:host([data-spui-appearance=glass]) .surface,:host-context([data-spui-appearance=glass]) .surface{backdrop-filter:blur(18px) saturate(1.35)}:host([appearance=brand]){--spui-popover-background:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4));--spui-popover-color:var(--spui-ui-accent-text,var(--spui-semantic-primary-button-text,#fff));--spui-popover-border:var(--spui-ui-accent,var(--colorBrandBackground,#0078d4))}:host([appearance=inverted]){--spui-popover-background:var(--spui-ui-text,var(--spui-semantic-body-text,#242424));--spui-popover-color:var(--spui-ui-surface,var(--spui-semantic-body-background,#fff));--spui-popover-border:var(--spui-ui-text,var(--spui-semantic-body-text,#242424))}:host([size=small]) .surface{padding:8px;font-size:12px}:host([size=large]) .surface{padding:20px;font-size:16px}@media(prefers-reduced-motion:reduce){.surface{transition:none}}@media(forced-colors:active){.surface{border-color:CanvasText;box-shadow:none}.surface:popover-open{outline:1px solid CanvasText}}`;
|
|
293
293
|
style.textContent += `:host([arrow]) .surface:before{content:"";position:absolute;z-index:1;width:8px;height:8px;border:1px solid var(--spui-popover-border,var(--spui-ui-stroke,#d1d1d1));background:var(--spui-popover-background,var(--spui-ui-surface,#fff));transform:rotate(45deg)}:host([arrow]) .surface[data-placement=bottom]:before{inset-block-start:-5px;inset-inline-start:var(--spui-popover-arrow-inline-offset,calc(50% - 5px));border-inline-end:0;border-block-end:0}:host([arrow]) .surface[data-placement=top]:before{inset-block-end:-5px;inset-inline-start:var(--spui-popover-arrow-inline-offset,calc(50% - 5px));border-inline-start:0;border-block-start:0}:host([arrow]) .surface[data-placement=left]:before{inset-inline-end:-5px;inset-block-start:var(--spui-popover-arrow-block-offset,calc(50% - 5px));border-inline-start:0;border-block-end:0}:host([arrow]) .surface[data-placement=right]:before{inset-inline-start:-5px;inset-block-start:var(--spui-popover-arrow-block-offset,calc(50% - 5px));border-inline-end:0;border-block-start:0}`;
|
|
294
294
|
const panel = document.createElement("div");
|
|
295
295
|
panel.className = "surface";
|