@spfx-fast/sharepoint-ui 0.4.2 → 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 +3 -1
- package/components.json +168 -28
- 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 +142 -10
- package/dist/react.js +306 -46
- 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
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";
|
package/dist/elements/rating.js
CHANGED
|
@@ -5,7 +5,7 @@ export function defineRating() {
|
|
|
5
5
|
return;
|
|
6
6
|
class SpuiRating extends HTMLElement {
|
|
7
7
|
static formAssociated = true;
|
|
8
|
-
static observedAttributes = ["value", "default-value", "max", "step", "size", "color", "label", "item-label", "name", "disabled", "readonly", "required", "aria-label", "aria-labelledby", "aria-description", "aria-describedby"];
|
|
8
|
+
static observedAttributes = ["value", "default-value", "max", "step", "size", "color", "label", "item-label", "name", "disabled", "readonly", "required", "required-message", "aria-label", "aria-labelledby", "aria-description", "aria-describedby"];
|
|
9
9
|
internals;
|
|
10
10
|
instanceName = `spui-rating-${crypto.randomUUID()}`;
|
|
11
11
|
rating = 0;
|
|
@@ -96,7 +96,7 @@ export function defineRating() {
|
|
|
96
96
|
this.internals?.setFormValue(this.rating > 0 ? String(this.rating) : null, String(this.rating));
|
|
97
97
|
const missing = this.hasAttribute("required") && this.rating === 0;
|
|
98
98
|
try {
|
|
99
|
-
this.internals?.setValidity(missing ? { valueMissing: true } : {}, missing ? "Choose a rating." : "", this.queryInputs()[0]);
|
|
99
|
+
this.internals?.setValidity(missing ? { valueMissing: true } : {}, missing ? this.getAttribute("required-message") || "Choose a rating." : "", this.queryInputs()[0]);
|
|
100
100
|
}
|
|
101
101
|
catch { /* Keep the radio group functional if a browser rejects the validity anchor. */ }
|
|
102
102
|
}
|
|
@@ -164,7 +164,7 @@ export function defineRating() {
|
|
|
164
164
|
group.append(starItem);
|
|
165
165
|
}
|
|
166
166
|
const style = document.createElement("style");
|
|
167
|
-
style.textContent = `${base}:host{display:inline-grid;gap:4px;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font-family:var(--spui-font-family,inherit)}.label{font-size:14px;font-weight:600;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit))}.label[hidden]{display:none}.items{display:inline-flex;align-items:center;gap:2px;width:max-content}.star{position:relative;display:inline-block;flex:none;width:var(--spui-rating-size,28px);height:var(--spui-rating-size,28px)}.icon{position:relative;display:inline-block;font-size:var(--spui-rating-size,28px);line-height:1;color:var(--spui-rating-empty,color-mix(in srgb,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 65%,var(--spui-ui-surface,var(--spui-semantic-body-background,#ffffff)) 35%));user-select:none}.fill{position:absolute;inset-block:0;inset-inline-start:0;overflow:hidden;width:0;color:var(--spui-rating-color,var(--spui-ui-accent,#0078d4));white-space:nowrap}:host([color=brand]){--spui-rating-color:color-mix(in srgb,var(--spui-ui-accent,#0078d4) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host([color=marigold]){--spui-rating-color:color-mix(in srgb,var(--spui-rating-marigold,#c58b00) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host(:not([color])),:host([color=neutral]){--spui-rating-color:var(--spui-ui-text,var(--spui-semantic-body-text,currentColor))}:host([size=small]){--spui-rating-size:18px}:host([size=medium]){--spui-rating-size:24px}:host([size=large]){--spui-rating-size:30px}:host([size=extra-large]),:host(:not([size])){--spui-rating-size:36px}.hit{position:absolute;z-index:1;inset-block:0;display:block;cursor:pointer}.hit.whole{inset-inline:0}.hit.half{inset-inline-start:0;width:50%}.hit.full{inset-inline-end:0;width:50%}.hit input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:inherit}.hit:focus-within{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline-offset:2px;border-radius:3px}:host([disabled]) .hit,:host([readonly]) .hit{cursor:default}@media(forced-colors:active){.icon{color:CanvasText}.fill{color:Highlight}.hit:focus-within{outline-color:Highlight}}`;
|
|
167
|
+
style.textContent = `${base}:host{display:inline-grid;gap:4px;min-width:0;color:var(--spui-ui-text,var(--spui-semantic-body-text,inherit));font-family:var(--spui-font-family,inherit)}.label{font-size:14px;font-weight:600;color:var(--spui-ui-muted,var(--spui-semantic-body-text,inherit))}.label[hidden]{display:none}.items{display:inline-flex;align-items:center;gap:2px;width:max-content}.star{position:relative;display:inline-block;flex:none;width:var(--spui-rating-size,28px);height:var(--spui-rating-size,28px)}.icon{position:relative;display:inline-block;font-size:var(--spui-rating-size,28px);line-height:1;color:var(--spui-rating-empty,color-mix(in srgb,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 65%,var(--spui-ui-surface,var(--spui-semantic-body-background,#ffffff)) 35%));user-select:none}.fill{position:absolute;inset-block:0;inset-inline-start:0;overflow:hidden;width:0;color:var(--spui-rating-color,var(--spui-ui-accent,#0078d4));white-space:nowrap}:host([color=brand]){--spui-rating-color:color-mix(in srgb,var(--spui-ui-accent,#0078d4) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host([color=marigold]){--spui-rating-color:color-mix(in srgb,var(--spui-rating-marigold,#c58b00) 65%,var(--spui-ui-text,var(--spui-semantic-body-text,#242424)) 35%)}:host(:not([color])),:host([color=neutral]){--spui-rating-color:var(--spui-ui-text,var(--spui-semantic-body-text,currentColor))}:host([size=small]){--spui-rating-size:18px}:host([size=medium]){--spui-rating-size:24px}:host([size=large]){--spui-rating-size:30px}:host([size=extra-large]),:host(:not([size])){--spui-rating-size:36px}.hit{position:absolute;z-index:1;inset-block:0;display:block;cursor:pointer}.hit.whole{inset-inline:0}.hit.half{inset-inline-start:0;width:50%}.hit.full{inset-inline-end:0;width:50%}.hit input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:inherit}.hit input:focus-visible{outline:0}.hit:focus-within{outline:2px solid var(--spui-focus-ring,var(--spui-ui-accent,#0078d4));outline-offset:2px;border-radius:3px}:host([disabled]) .hit,:host([readonly]) .hit{cursor:default}@media(forced-colors:active){.icon{color:CanvasText}.fill{color:Highlight}.hit:focus-within{outline-color:Highlight}}`;
|
|
168
168
|
const templates = document.createElement("div");
|
|
169
169
|
templates.hidden = true;
|
|
170
170
|
for (const slotName of ["icon-filled", "icon-outline", "full-value-input", "half-value-input"]) {
|
|
@@ -1,6 +1,20 @@
|
|
|
1
|
+
export { getRichTextEditorFieldOptions, type SharePointMultiLineField } from "../sharepoint-fields.js";
|
|
2
|
+
export type RichTextEditorLink = {
|
|
3
|
+
href: string;
|
|
4
|
+
text?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
openInNewTab?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type RichTextEditorLinkPicker = (currentLink: RichTextEditorLink | null) => Promise<RichTextEditorLink | null>;
|
|
9
|
+
export type RichTextEditorImageUploadResult = string | {
|
|
10
|
+
src: string;
|
|
11
|
+
alt: string;
|
|
12
|
+
};
|
|
13
|
+
export type RichTextEditorImageUploader = (file: File) => Promise<RichTextEditorImageUploadResult>;
|
|
1
14
|
export interface SharePointRichTextEditorElement extends HTMLElement {
|
|
2
15
|
value: string;
|
|
3
|
-
uploadImage?:
|
|
16
|
+
uploadImage?: RichTextEditorImageUploader;
|
|
17
|
+
linkPicker?: RichTextEditorLinkPicker;
|
|
4
18
|
readonly form: HTMLFormElement | null;
|
|
5
19
|
readonly validity: ValidityState | undefined;
|
|
6
20
|
readonly validationMessage: string;
|