@salsita-ai/sdk 0.50.0-develop.ef06ca4ac1 → 0.50.0-develop.f101f4c3c9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configurator/common/configurator-interface.d.ts +52 -2
- package/dist/configurator/common/configurator-interface.js +1 -1
- package/dist/configurator/configurator-context/configurator-hooks/layout-hooks.d.ts +4 -0
- package/dist/configurator/index.d.ts +1 -0
- package/dist/configurator/index.js +1 -1
- package/dist/configurator/pages/default-configurator-elements.d.ts +3 -2
- package/dist/configurator/pages/default-configurator-elements.js +1 -1
- package/dist/configurator/pages/default-elements/index.d.ts +1 -0
- package/dist/configurator/pages/default-elements/index.js +1 -1
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInAddEntityFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInAddEntityFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInDeleteEntityFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInDeleteEntityFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInNavigationHotspot.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInNavigationHotspot.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInSelectionHotspot.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInSelectionHotspot.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInToolMenuFab.d.ts +3 -0
- package/dist/configurator/pages/default-elements/scene-controls/BuiltInToolMenuFab.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/index.d.ts +6 -0
- package/dist/configurator/pages/default-elements/scene-controls/index.js +1 -0
- package/dist/configurator/pages/default-elements/scene-controls/scene-control-elements.d.ts +6 -0
- package/dist/configurator/pages/default-elements/scene-controls/scene-control-elements.js +1 -0
- package/dist/configurator/scene/index.d.ts +1 -0
- package/dist/configurator/scene/index.js +1 -1
- package/dist/configurator/scene/scene-controls/ToolFab.d.ts +4 -0
- package/dist/configurator/scene/scene-controls/ToolFab.js +1 -1
- package/dist/configurator/scene/scene-controls/use-scene-control-tooltip.d.ts +2 -1
- package/dist/configurator/scene/scene-entity/scene-controls/SceneEntityHtmlHotspots.js +1 -1
- package/dist/configurator/toolbar-actions/index.d.ts +3 -0
- package/dist/configurator/toolbar-actions/index.js +1 -0
- package/dist/configurator/toolbar-actions/use-assistant-panel.d.ts +18 -0
- package/dist/configurator/toolbar-actions/use-assistant-panel.js +1 -0
- package/dist/configurator/toolbar-actions/use-measurements.d.ts +35 -0
- package/dist/configurator/toolbar-actions/use-measurements.js +1 -0
- package/dist/configurator/toolbar-actions/use-toolbar-actions.d.ts +100 -0
- package/dist/configurator/toolbar-actions/use-toolbar-actions.js +1 -0
- package/dist/configurator/toolbar-actions/use-toolbar-help.d.ts +7 -0
- package/dist/configurator/toolbar-actions/use-toolbar-help.js +1 -0
- package/dist/configurator/ui/assistant/AssistantMarkdown.d.ts +1 -1
- package/dist/configurator/ui/assistant/AssistantMarkdown.js +1 -1
- package/dist/configurator/ui/assistant/alert/AssistantAlert.d.ts +8 -0
- package/dist/configurator/ui/assistant/alert/AssistantAlert.js +1 -0
- package/dist/configurator/ui/assistant/alert/index.d.ts +2 -0
- package/dist/configurator/ui/assistant/alert/index.js +1 -0
- package/dist/configurator/ui/assistant/alert/remark-alerts.d.ts +10 -0
- package/dist/configurator/ui/assistant/alert/remark-alerts.js +1 -0
- package/dist/configurator/ui/assistant/form/AssistantForm.js +1 -1
- package/dist/configurator/ui/assistant/form/built-in-form-registry.js +1 -1
- package/dist/configurator/ui/assistant/form/compose-answer.d.ts +2 -1
- package/dist/configurator/ui/assistant/form/compose-answer.js +1 -1
- package/dist/configurator/ui/assistant/form/form-model.d.ts +3 -2
- package/dist/configurator/ui/assistant/form/form-registry.d.ts +1 -1
- package/dist/configurator/ui/assistant/form/form-registry.js +2 -2
- package/dist/configurator/ui/assistant/form/parse-form-block.d.ts +2 -1
- package/dist/configurator/ui/assistant/form/parse-form-block.js +1 -1
- package/dist/configurator/ui/assistant/form/read-form-attributes.js +1 -1
- package/dist/configurator/ui/assistant/form-elements/FormCard.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormCard.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormConfirm.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormConfirm.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormGroup.d.ts +4 -1
- package/dist/configurator/ui/assistant/form-elements/FormNumber.d.ts +9 -0
- package/dist/configurator/ui/assistant/form-elements/FormNumber.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormOptions.d.ts +4 -1
- package/dist/configurator/ui/assistant/form-elements/FormReply.d.ts +4 -1
- package/dist/configurator/ui/assistant/form-elements/FormSwatch.d.ts +10 -0
- package/dist/configurator/ui/assistant/form-elements/FormSwatch.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/FormText.d.ts +4 -1
- package/dist/configurator/ui/assistant/form-elements/FormText.js +1 -1
- package/dist/configurator/ui/assistant/form-elements/clamp-form-number.d.ts +10 -0
- package/dist/configurator/ui/assistant/form-elements/clamp-form-number.js +1 -0
- package/dist/configurator/ui/assistant/form-elements/form-element-props.d.ts +17 -13
- package/dist/configurator/ui/assistant/form-elements/index.d.ts +4 -0
- package/dist/configurator/ui/assistant/form-elements/index.js +1 -1
- package/dist/configurator/ui/assistant/resource-image/index.d.ts +1 -1
- package/dist/configurator/ui/assistant/resource-image/index.js +1 -1
- package/dist/configurator/ui/assistant/resource-image/resource-path.d.ts +0 -9
- package/dist/configurator/ui/assistant/resource-image/resource-path.js +1 -1
- package/dist/configurator/ui/assistant/streamed-markdown.d.ts +2 -2
- package/dist/configurator/ui/assistant/streamed-markdown.js +2 -2
- package/dist/configurator/ui/phoenix-layout-elements/AssistantToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LanguageMenuAction.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/LanguageToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/MeasurementsMenuAction.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/MeasurementsToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/ShareToolbarButton.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/DimensionUnitSelector.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/MeasurementsIndicatorsSwitch.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/share/ShareModal.js +1 -1
- package/dist/configurator/ui/phoenix-layout-elements/share/use-share.d.ts +7 -8
- package/dist/configurator/ui/phoenix-layout-elements/share/use-share.js +1 -1
- package/dist/docs/complex-use-cases/focus-mode.mdx +2 -0
- package/dist/docs/fabs/basic.mdx +4 -0
- package/dist/docs/index.json +1 -1
- package/dist/docs/layouts/custom-layout.mdx +3 -1
- package/dist/docs/other-features/navigation-hotspot.mdx +2 -0
- package/dist/docs/phoenix/configurator-interface.mdx +68 -1
- package/dist/docs/phoenix/sdk-builder-workflow.mdx +1 -1
- package/dist/docs/selection-and-highlight/hotspots.mdx +2 -0
- package/dist/domain/application/assistant/form/assistant-form-elements.d.ts +163 -0
- package/dist/domain/application/assistant/form/assistant-form-elements.js +1 -0
- package/dist/domain/application/assistant/form/assistant-resource-path.d.ts +10 -0
- package/dist/domain/application/assistant/form/assistant-resource-path.js +1 -0
- package/dist/domain/application/assistant/form/get-assistant-form-value-attribute.d.ts +6 -0
- package/dist/domain/application/assistant/form/get-assistant-form-value-attribute.js +1 -0
- package/dist/domain/application/assistant/form/index.d.ts +4 -0
- package/dist/domain/application/assistant/form/index.js +1 -0
- package/dist/domain/application/assistant/generate-assistant-prompt.d.ts +3 -0
- package/dist/domain/application/assistant/generate-assistant-prompt.js +1 -1
- package/dist/domain/application/assistant/index.d.ts +1 -2
- package/dist/domain/application/assistant/index.js +1 -1
- package/dist/i18n/locales/cs/messages.js +1 -1
- package/dist/i18n/locales/da/messages.js +1 -1
- package/dist/i18n/locales/de/messages.js +1 -1
- package/dist/i18n/locales/de-AT/messages.js +1 -1
- package/dist/i18n/locales/en/messages.js +1 -1
- package/dist/i18n/locales/en-AU/messages.js +1 -1
- package/dist/i18n/locales/en-GB/messages.js +1 -1
- package/dist/i18n/locales/es/messages.js +1 -1
- package/dist/i18n/locales/fr/messages.js +1 -1
- package/dist/i18n/locales/hu/messages.js +1 -1
- package/dist/i18n/locales/it/messages.js +1 -1
- package/dist/i18n/locales/nl/messages.js +1 -1
- package/dist/i18n/locales/pl/messages.js +1 -1
- package/dist/i18n/locales/pt/messages.js +1 -1
- package/dist/i18n/locales/ro/messages.js +1 -1
- package/dist/i18n/locales/sk/messages.js +1 -1
- package/dist/i18n/locales/tr/messages.js +1 -1
- package/dist/react-sdk/domain-context/index.d.ts +3 -0
- package/dist/react-sdk/domain-context/index.js +1 -1
- package/dist/react-sdk/domain-context/system-hooks/generate-share-link-hooks.d.ts +8 -0
- package/dist/react-sdk/domain-context/system-hooks/generate-share-link-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/locale-switch-hooks.d.ts +24 -0
- package/dist/react-sdk/domain-context/system-hooks/locale-switch-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/share-links-hooks.d.ts +32 -0
- package/dist/react-sdk/domain-context/system-hooks/share-links-hooks.js +1 -0
- package/dist/react-sdk/domain-context/system-hooks/undo-redo-hooks.js +1 -1
- package/dist/react-sdk/index.d.ts +1 -0
- package/dist/react-sdk/index.js +1 -1
- package/dist/react-sdk/scene-control-elements/AddEntityFabElement.d.ts +36 -0
- package/dist/react-sdk/scene-control-elements/AddEntityFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/DeleteEntityFabElement.d.ts +44 -0
- package/dist/react-sdk/scene-control-elements/DeleteEntityFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/NavigationHotspotElement.d.ts +38 -0
- package/dist/react-sdk/scene-control-elements/NavigationHotspotElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/SelectionHotspotElement.d.ts +30 -0
- package/dist/react-sdk/scene-control-elements/SelectionHotspotElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/ToolMenuFabElement.d.ts +30 -0
- package/dist/react-sdk/scene-control-elements/ToolMenuFabElement.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-add-entity-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-add-entity-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-delete-entity-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-delete-entity-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-navigation-hotspot.d.ts +10 -0
- package/dist/react-sdk/scene-control-elements/create-navigation-hotspot.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-selection-hotspot.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-selection-hotspot.js +1 -0
- package/dist/react-sdk/scene-control-elements/create-tool-menu-fab.d.ts +9 -0
- package/dist/react-sdk/scene-control-elements/create-tool-menu-fab.js +1 -0
- package/dist/react-sdk/scene-control-elements/index.d.ts +11 -0
- package/dist/react-sdk/scene-control-elements/index.js +1 -0
- package/dist/react-sdk/scene-control-elements/scene-control-tooltip-visibility.d.ts +5 -0
- package/dist/react-sdk/scene-control-elements/scene-control-tooltip-visibility.js +1 -0
- package/dist/ui-sdk/icons/__generated/Lightbulb.d.ts +3 -0
- package/dist/ui-sdk/icons/__generated/Lightbulb.js +1 -0
- package/dist/ui-sdk/icons/__generated/XCircle.d.ts +3 -0
- package/dist/ui-sdk/icons/__generated/XCircle.js +1 -0
- package/dist/ui-sdk/icons/__generated/index.d.ts +4 -0
- package/dist/ui-sdk/icons/__generated/index.js +1 -1
- package/dist/ui-sdk/icons/icons-registry.js +1 -1
- package/dist/ui-sdk/theme/types.d.ts +1 -1
- package/package.json +3 -3
- package/dist/configurator/ui/phoenix-layout-elements/language/use-locale-options.d.ts +0 -4
- package/dist/configurator/ui/phoenix-layout-elements/language/use-locale-options.js +0 -1
- package/dist/configurator/ui/phoenix-layout-elements/measurements/use-measurements-visibility.d.ts +0 -4
- package/dist/configurator/ui/phoenix-layout-elements/measurements/use-measurements-visibility.js +0 -1
- package/dist/domain/application/assistant/assistant-form-elements.d.ts +0 -28
- package/dist/domain/application/assistant/assistant-form-elements.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,Fragment as r}from"react/jsx-runtime";import{styled as n}from"@mui/material";import{createContext as i,memo as o,useContext as t,useMemo as l}from"react";import a,{defaultUrlTransform as d}from"react-markdown";import m from"remark-gfm";import{
|
|
1
|
+
import{jsx as e,Fragment as r}from"react/jsx-runtime";import{styled as n}from"@mui/material";import{createContext as i,memo as o,useContext as t,useMemo as l}from"react";import a,{defaultUrlTransform as d}from"react-markdown";import m from"remark-gfm";import{AssistantAlert as s,isAlertKind as c,remarkAlerts as u}from"./alert/index.js";import{AssistantEntityLink as p}from"./entity-link/index.js";import{AssistantForm as h}from"./form/index.js";import{AssistantReferenceLink as f,isAssistantLinkHref as g,parseAssistantLinkTarget as k}from"./reference-link/index.js";import{AssistantImage as b}from"./resource-image/index.js";import{completeStreamedMarkdown as v,hasOpenFence as x}from"./streamed-markdown.js";import{AssistantPanelName as y}from"./theme.js";let j=n("div",{name:y,slot:"assistantMessage"})(({theme:{palette:e,shape:r,spacing:n,typography:i}})=>({overflowWrap:"anywhere","& > :first-child":{marginBlockStart:0},"& > :last-child":{marginBlockEnd:0},"p, ul, ol, pre, blockquote":{marginBlock:n(1)},"h1, h2, h3, h4, h5, h6":{...i.subtitle2,marginBlock:n(1.5,.5)},"ul, ol":{paddingInlineStart:n(2.5)},a:{color:e.primary.main},code:{background:e.action.hover,borderRadius:r.borderRadius/2,fontFamily:"ui-monospace, Menlo, monospace",fontSize:"0.9em",paddingInline:n(.5)},pre:{background:e.action.hover,borderRadius:r.borderRadius,overflowX:"auto",padding:n(1),code:{background:"none",padding:0}},blockquote:{borderInlineStart:`2px solid ${e.divider}`,color:e.text.secondary,marginInline:0,paddingInlineStart:n(1.5)},"th, td":{borderBlockEnd:`1px solid ${e.divider}`,padding:n(.5,1),textAlign:"start",verticalAlign:"top"}})),w=n("div")({overflowX:"auto",table:{borderCollapse:"collapse",inlineSize:"100%"}}),S=i({forms:"hidden",openFenceEnd:void 0,isStreaming:!1}),A=({source:r,end:n})=>{let{forms:i,openFenceEnd:o,isStreaming:l}=t(S);return"hidden"===i?null:null!=n&&n===o?l?e(h,{source:r,status:"writing"}):null:e(h,{source:r,status:"disabled"===i?"waiting":"ready"})},B={a:({node:n,children:i,href:o,...t})=>{if(null==o||!g(o))return e("a",{...t,href:o,target:"_blank",rel:"noopener noreferrer",children:i});let l=k(o);return null==l?e(r,{children:i}):"entity"===l.kind?e(p,{id:l.id,children:i}):e(f,{target:l,children:i})},blockquote:({node:r,children:n,...i})=>{let o=r?.properties.dataAlert;return c(o)?e(s,{kind:o,children:n}):e("blockquote",{...i,children:n})},img:({src:r,alt:n})=>e(b,{src:r,alt:n}),pre:({node:r,children:n,...i})=>{let o=(e=>{let[r]=e?.children??[];if(r?.type!=="element"||"code"!==r.tagName)return;let{className:n}=r.properties;if(Array.isArray(n)&&n.includes("language-form"))return r.children.map(e=>"text"===e.type?e.value:"").join("")})(r);return null==o?e("pre",{...i,children:n}):e(A,{source:o,end:r?.position?.end.offset})},table:({node:r,children:n,...i})=>e(w,{children:e("table",{...i,children:n})})},I=[m,u],q=e=>g(e)?e:d(e);export const AssistantMarkdown=o(({markdown:r,isStreaming:n,forms:i})=>{let o=n?v(r):r,t=x(r)?o.length:void 0,d=l(()=>({forms:i,openFenceEnd:t,isStreaming:n}),[i,t,n]);return e(j,{children:e(S.Provider,{value:d,children:e(a,{components:B,remarkPlugins:I,urlTransform:q,children:o})})})});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { AlertKind } from './remark-alerts.js';
|
|
3
|
+
export interface AssistantAlertProps {
|
|
4
|
+
readonly kind: AlertKind;
|
|
5
|
+
readonly children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/** A GitHub alert in a reply: its content as Markdown, marked by the colour and icon of its kind. */
|
|
8
|
+
export declare const AssistantAlert: import("react").MemoExoticComponent<({ kind, children }: AssistantAlertProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as r,jsxs as i}from"react/jsx-runtime";import{alpha as o,styled as t}from"@mui/material";import{memo as n}from"react";import{PhxIcon as a}from"#package/ui-sdk";import{AssistantPanelName as e}from"../theme.js";let l={note:{color:"info",icon:"Info"},tip:{color:"success",icon:"Lightbulb"},important:{color:"primary",icon:"WarningCircle"},warning:{color:"warning",icon:"Warning"},caution:{color:"error",icon:"XCircle"}},c=t("div",{name:e,slot:"alert"})(({theme:{palette:r,shape:i,spacing:t,typography:n}})=>({borderInlineStart:"3px solid",borderRadius:i.borderRadius,display:"grid",gap:t(1),gridTemplateColumns:"min-content minmax(0, 1fr)",marginBlock:t(1),padding:t(1,1.5),...Object.fromEntries(Object.entries(l).map(([i,{color:t}])=>[`&[data-alert="${i}"]`,{background:o(r[t].main,.08),borderInlineStartColor:r[t].main,"& > :first-child":{color:r[t].main}}])),"& > :last-child > :first-child":{marginBlockStart:0},"& > :last-child > :last-child":{marginBlockEnd:0},"& > :first-child":{blockSize:`calc(${n.body2.lineHeight} * 1em)`,display:"grid",placeItems:"center"}}));export const AssistantAlert=n(({kind:o,children:t})=>i(c,{role:"note","data-alert":o,children:[r("span",{children:r(a,{name:l[o].icon})}),r("div",{children:t})]}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{AssistantAlert}from"./AssistantAlert.js";export{isAlertKind,remarkAlerts}from"./remark-alerts.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Root } from 'mdast';
|
|
2
|
+
/** The kinds of GitHub alerts a reply can write, each with its own colour and icon. */
|
|
3
|
+
export type AlertKind = 'note' | 'tip' | 'important' | 'warning' | 'caution';
|
|
4
|
+
export declare const isAlertKind: (value: unknown) => value is AlertKind;
|
|
5
|
+
/**
|
|
6
|
+
* Remark plugin for GitHub alerts: a blockquote whose first line is a marker such as `[!WARNING]`
|
|
7
|
+
* loses the marker and carries its kind as the `dataAlert` property (`data-alert` in the page), for the `blockquote` override to render as a
|
|
8
|
+
* callout. A blockquote with an unknown marker stays as it is.
|
|
9
|
+
*/
|
|
10
|
+
export declare const remarkAlerts: () => (tree: Root) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
let e=["note","tip","important","warning","caution"],t=/^\[!([a-z]+)\][ \t]*(?:\n|$)/i;export const isAlertKind=t=>"string"==typeof t&&e.some(e=>e===t);let r=e=>{let[r]=e.children;if(r?.type!=="paragraph")return;let[n,l]=r.children;if(n?.type!=="text")return;let i=t.exec(n.value),a=i?.[1]?.toLowerCase();if(null==i||!isAlertKind(a))return;let o=n.value.slice(i[0].length),c=!i[0].endsWith("\n")&&l?.type==="break";if(i[0].endsWith("\n")||null==l||c)return""===o?r.children.splice(0,c?2:1):n.value=o,0===r.children.length&&e.children.shift(),a},n=e=>{for(let t of e){if("blockquote"===t.type){let e=r(t);if(null!=e){t.data={...t.data,hProperties:{...t.data?.hProperties,dataAlert:e}};continue}}"children"in t&&n(t.children)}};export const remarkAlerts=()=>e=>{n(e.children)};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t,styled as o}from"@mui/material";import{memo as n,useCallback as a,useEffect as s,useMemo as l,useState as d}from"react";import{match as m}from"ts-pattern";import{useConfigurator as c}from"../../../application-runtime/index.js";import{AssistantPanelName as p}from"../theme.js";import{getBuiltInFormRegistry as u}from"./built-in-form-registry.js";import{composeAnswer as b}from"./compose-answer.js";import{describeBuildErrors as f}from"./describe-build-errors.js";import{parseFormBlock as g}from"./parse-form-block.js";let h=o("form",{name:p,slot:"form"})(({theme:{spacing:e}})=>({display:"flex",flexDirection:"column",gap:e(1.5),marginBlock:e(1)})),k=o(t,{name:p,slot:"formSubmit"})(({theme:{palette:e,spacing:i,typography:r}})=>({...r.body2,alignSelf:"end",background:e.primary.main,border:"none",borderRadius:8,color:e.primary.contrastText,fontWeight:r.fontWeightMedium,letterSpacing:"normal",minBlockSize:0,minInlineSize:0,paddingBlock:i(.5),paddingInline:i(2),textTransform:"none","&:hover":{background:e.primary.dark,border:"none"},"&.Mui-disabled":{background:e.action.disabledBackground,border:"none",color:e.action.disabled}})),w=o("div",{name:p,slot:"formNote"})(({theme:{palette:e,shape:i,spacing:r,typography:t}})=>({...t.caption,alignItems:"center",background:e.action.hover,borderRadius:i.borderRadius,color:e.text.secondary,display:"flex",flexWrap:"wrap",gap:r(1),justifyContent:"space-between",marginBlock:r(1),paddingBlock:r(1),paddingInline:r(1.5)})),x=({model:t,disabled:o,send:n})=>{let[a,s]=d(()=>new Map),[l,c]=d(()=>new Map),p=(i,r)=>{let{id:d,definition:u,label:f,value:g,attributes:h}=i;return m(u).with({role:"option"},({component:m})=>e(m,{attributes:h,label:f,disabled:o,selected:!0===a.get(d),onSelect:()=>{t.isQuick?n(b(t,new Map([[i.id,!0]]),l)):s(e=>{let t=new Map(e);if("choice"===r.definition.role){for(let e of r.children)t.delete(e.id);t.set(i.id,!0)}else t.set(i.id,!0!==e.get(i.id));return t})}},d)).with({role:"input"},({component:r})=>e(r,{attributes:h,label:f,
|
|
1
|
+
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Trans as r}from"@lingui/react";import{Button as t,styled as o}from"@mui/material";import{memo as n,useCallback as a,useEffect as s,useMemo as l,useState as d}from"react";import{match as m}from"ts-pattern";import{useConfigurator as c}from"../../../application-runtime/index.js";import{AssistantPanelName as p}from"../theme.js";import{getBuiltInFormRegistry as u}from"./built-in-form-registry.js";import{composeAnswer as b}from"./compose-answer.js";import{describeBuildErrors as f}from"./describe-build-errors.js";import{parseFormBlock as g}from"./parse-form-block.js";let h=o("form",{name:p,slot:"form"})(({theme:{spacing:e}})=>({display:"flex",flexDirection:"column",gap:e(1.5),marginBlock:e(1)})),k=o(t,{name:p,slot:"formSubmit"})(({theme:{palette:e,spacing:i,typography:r}})=>({...r.body2,alignSelf:"end",background:e.primary.main,border:"none",borderRadius:8,color:e.primary.contrastText,fontWeight:r.fontWeightMedium,letterSpacing:"normal",minBlockSize:0,minInlineSize:0,paddingBlock:i(.5),paddingInline:i(2),textTransform:"none","&:hover":{background:e.primary.dark,border:"none"},"&.Mui-disabled":{background:e.action.disabledBackground,border:"none",color:e.action.disabled}})),w=o("div",{name:p,slot:"formNote"})(({theme:{palette:e,shape:i,spacing:r,typography:t}})=>({...t.caption,alignItems:"center",background:e.action.hover,borderRadius:i.borderRadius,color:e.text.secondary,display:"flex",flexWrap:"wrap",gap:r(1),justifyContent:"space-between",marginBlock:r(1),paddingBlock:r(1),paddingInline:r(1.5)})),x=({model:t,disabled:o,send:n})=>{let[a,s]=d(()=>new Map),[l,c]=d(()=>new Map),p=(i,r)=>{let{id:d,definition:u,label:f,value:g,attributes:h}=i;return m(u).with({role:"option"},({component:m})=>e(m,{attributes:h,label:f,value:g,disabled:o,selected:!0===a.get(d),onSelect:()=>{t.isQuick?n(b(t,new Map([[i.id,!0]]),l)):s(e=>{let t=new Map(e);if("choice"===r.definition.role){for(let e of r.children)t.delete(e.id);t.set(i.id,!0)}else t.set(i.id,!0!==e.get(i.id));return t})}},d)).with({role:"input"},({component:r})=>e(r,{attributes:h,label:f,disabled:o,state:a.get(d),onChange:(e,r)=>{t.isQuick?n(b(t,new Map([[i.id,e]]),new Map([[i.id,r]]))):(s(r=>new Map(r).set(i.id,e)),c(e=>new Map(e).set(i.id,r)))}},d)).with({role:"group"},{role:"choice"},{role:"choices"},({component:r})=>e(r,{attributes:h,label:f,disabled:o,children:i.children.map(e=>p(e,i))},d)).exhaustive()};return i(h,{onSubmit:e=>{e.preventDefault(),o||t.isQuick||n(b(t,a,l))},children:[t.root.children.map(e=>p(e,t.root)),!t.isQuick&&e(k,{type:"submit",variant:"contained",disabled:o,disableElevation:!0,children:e(r,{id:"sdk.assistant.form.submit.label",message:"Submit"})})]})};export const AssistantForm=n(({source:o,status:n})=>{let{assistantSystem:m}=c(),[p,b]=d(!1),h="writing"===n,k=l(()=>h?void 0:g(o,u()),[o,h]),y="ready"!==n||p,j=a(e=>{b(!0),m.send(e).finally(()=>b(!1))},[m]);return(s(()=>{k?.ok===!1&&console.warn("The assistant wrote a form that could not be built.",k.errors)},[k]),k)?k.ok?0===k.root.children.length?null:e(x,{model:k,disabled:y,send:j}):i(w,{role:"alert",children:[e("span",{children:e(r,{id:"sdk.assistant.form.failure",message:"The assistant couldn't build this form."})}),e(t,{size:"small",variant:"outlined",color:"inherit",disabled:y,onClick:()=>j(f(k.errors)),children:e(r,{id:"sdk.assistant.form.fix.label",message:"Fix it"})})]}):e(w,{children:e(r,{id:"sdk.assistant.form.writing",message:"Preparing a form…"})})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
let o;import{match as t}from"ts-pattern";import{ASSISTANT_BUILT_IN_FORM_ELEMENTS as e,extendedSchemaValidator as r}from"#package/domain";import{
|
|
1
|
+
let o;import{match as t}from"ts-pattern";import{ASSISTANT_BUILT_IN_FORM_ELEMENTS as e,extendedSchemaValidator as r}from"#package/domain";import{FormCard as i,FormConfirm as m,FormGroup as n,FormNumber as c,FormOptions as p,FormReply as s,FormSwatch as a,FormText as h}from"../form-elements/index.js";import{createFormRegistry as l}from"./form-registry.js";let f={group:n,choice:p,choices:p,reply:s,card:i,swatch:a,text:h,number:c,confirm:m};export const BUILT_IN_FORM_ELEMENTS=e.map(o=>{let e;return e=f[o.name],t(o.role).with("group","choice","choices",t=>({...o,role:t,component:e})).with("option",t=>({...o,role:t,component:e})).with("input",t=>({...o,role:t,component:e})).exhaustive()});export const getBuiltInFormRegistry=()=>o??=l(BUILT_IN_FORM_ELEMENTS,{schemaValidator:r});
|
|
@@ -6,6 +6,7 @@ export declare const FORM_PLACEHOLDER = "\u2014";
|
|
|
6
6
|
* The user's answer to a form, sent as their message: one line per labelled container or input as
|
|
7
7
|
* `Label: value`, a bare line for an unlabelled one, two spaces of indentation per labelled
|
|
8
8
|
* container, and the placeholder for anything unanswered. Unlabelled groups are flattened into
|
|
9
|
-
* their parent, and a picked option answers with its value, or its label without one
|
|
9
|
+
* their parent, and a picked option answers with its value, or its label without one, or else the first of its
|
|
10
|
+
* identity attributes it has.
|
|
10
11
|
*/
|
|
11
12
|
export declare const composeAnswer: (model: BuiltFormModel, state: FormState, answers: FormAnswers) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{match as t}from"ts-pattern";export const FORM_PLACEHOLDER="—";let e=(t,e)=>`${" ".repeat(t)}${e}`,n=(t,e)=>null==t?e:`${t}: ${e}`,r=({value:t,label:e})=>t
|
|
1
|
+
import{match as t}from"ts-pattern";export const FORM_PLACEHOLDER="—";let e=(t,e)=>`${" ".repeat(t)}${e}`,n=(t,e)=>null==t?e:`${t}: ${e}`,r=({value:t,label:e,attributes:n,definition:r})=>{let i=[t,e,...r.identity?.map(t=>n[t])??[]].find(t=>null!=t&&""!==t);return null==i?"":String(i)},i=({children:t},{state:e})=>t.filter(({id:t})=>!0===e.get(t)).map(r),l=(r,o,p)=>{let{label:u}=r;return t(r.definition.role).with("group",()=>{if(null==u)return r.children.flatMap(t=>l(t,o,p));let t=r.children.flatMap(t=>l(t,o+1,p));return t.length>0?[e(o,`${u}:`),...t]:[e(o,`${u}: —`)]}).with("choice",()=>[e(o,n(u,i(r,p)[0]??"—"))]).with("choices",()=>{let t=i(r,p);return 0===t.length?[e(o,n(u,"—"))]:null==u?t.map(t=>e(o,t)):[e(o,`${u}:`),...t.map(t=>e(o+1,t))]}).with("input",()=>[e(o,n(u,p.answers.get(r.id)??"—"))]).with("option",()=>[]).exhaustive()};export const composeAnswer=(t,e,n)=>l(t.root,0,{state:e,answers:n}).join("\n");
|
|
@@ -8,6 +8,7 @@ export interface FormNode {
|
|
|
8
8
|
readonly id: string;
|
|
9
9
|
readonly definition: FormElementDefinition;
|
|
10
10
|
readonly label?: string;
|
|
11
|
+
/** What an option answers with instead of its label. An input's starting `value` is among its attributes. */
|
|
11
12
|
readonly value?: string;
|
|
12
13
|
readonly attributes: Readonly<Record<string, unknown>>;
|
|
13
14
|
readonly children: readonly FormNode[];
|
|
@@ -21,8 +22,8 @@ export interface FormBuildError {
|
|
|
21
22
|
readonly message: string;
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
* A form fence as the panel renders it, or every reason it cannot. A quick form asks one question
|
|
25
|
-
* the first pick sends it, and it has no submit button.
|
|
25
|
+
* A form fence as the panel renders it, or every reason it cannot. A quick form asks one question,
|
|
26
|
+
* a choice or a quick input: the first pick or action sends it, and it has no submit button.
|
|
26
27
|
*/
|
|
27
28
|
export type FormModel = {
|
|
28
29
|
readonly ok: true;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type AssistantFormAttribute, type PhxValidateFunction, type SchemaValidator } from '#package/domain';
|
|
2
2
|
import type { FormElementDefinition } from './form-element-definition.js';
|
|
3
3
|
/** A declared attribute of a form element with the validator of its coerced value. */
|
|
4
4
|
export interface RegisteredFormAttribute {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
let
|
|
1
|
+
import{getAssistantFormValueAttribute as e}from"#package/domain";let t=new Set(`a abbr acronym address applet area article aside audio b base basefont bdi bdo big blink blockquote body br
|
|
2
2
|
button canvas caption center cite code col colgroup data datalist dd del details dfn dialog dir div dl dt em
|
|
3
3
|
embed fieldset figcaption figure font footer form frame frameset h1 h2 h3 h4 h5 h6 head header hgroup hr html
|
|
4
4
|
i iframe image img input ins kbd keygen label legend li link main map mark marquee math menu menuitem meta
|
|
5
5
|
meter nav nobr noembed noframes noscript object ol optgroup option output p param picture plaintext pre
|
|
6
6
|
progress q rb rp rt rtc ruby s samp script search section select slot small source span strike strong style
|
|
7
7
|
sub summary sup svg table tbody td template textarea tfoot th thead time title tr track tt u ul var video wbr
|
|
8
|
-
xmp`.split(/\s+/)),
|
|
8
|
+
xmp`.split(/\s+/)),r=/^[a-z][a-z0-9-]*$/,a={type:"string"},o=t=>{let r=e(t);return Object.entries({label:a,...r?{value:r}:{},...t.attributes})},n=(e,t)=>{let r=e.get(t);if(r?.definition.role!==t)throw Error(`The form registry has no "${t}" element with the role "${t}". Forms wrap implicit content in it. Register the built-in "${t}".`);return r};export const createFormRegistry=(e,{schemaValidator:a})=>{let i=new Map;for(let n of e){if(!r.test(n.name)||t.has(n.name))throw Error(`The form element "${n.name}" cannot be registered: its name must be lowercase and must not be an HTML element name, so form markup is never read as HTML. Rename the element.`);if(i.has(n.name))throw Error(`The form element "${n.name}" is registered twice. Each tag names one element. Remove or rename one of them.`);let e=new Map(o(n).map(([e,t])=>[e,{attribute:t,validate:a.compile({type:t.type,...t.enum?{enum:t.enum}:{},...null==t.pattern?{}:{pattern:t.pattern}})}]));i.set(n.name,{definition:n,attributes:e})}return{group:n(i,"group"),choice:n(i,"choice"),choices:n(i,"choices"),get:e=>i.get(e)}};
|
|
@@ -3,7 +3,8 @@ import type { FormRegistry } from './form-registry.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Builds a form from the markup of a ```` ```form ```` fence. A block whose only content is loose
|
|
5
5
|
* options asks one question, so they form an implicit `choice`; elsewhere loose options form an
|
|
6
|
-
* implicit `choices`. A block
|
|
6
|
+
* implicit `choices`. A block that asks one question, a choice or a quick input, is quick. A block
|
|
7
|
+
* with any unknown element, invalid attribute, misplaced element or option with nothing to show is
|
|
7
8
|
* not built at all, and every such error is returned.
|
|
8
9
|
*/
|
|
9
10
|
export declare const parseFormBlock: (source: string, registry: FormRegistry) => FormModel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Parser as e}from"htmlparser2";import{readFormAttributes as o}from"./read-form-attributes.js";let r=({name:e,attributes:o,position:r})=>({element:e,label:o.label,position:r}),t=({definition:e},o,r)=>({id:o,definition:e,attributes:{},children:r}),i=(e,o)=>{let r=[],i=[],
|
|
1
|
+
import{Parser as e}from"htmlparser2";import{readFormAttributes as o}from"./read-form-attributes.js";let r=({name:e,attributes:o,position:r})=>({element:e,label:o.label,position:r}),t=({definition:e},o,r)=>({id:o,definition:e,attributes:{},children:r}),i=(e,o)=>{let r=[],i=[],l=()=>{i.length>0&&(r.push(t(o.registry.choices,`choices-${i[0]?.id}`,i)),i=[])};for(let o of e)"option"===o.definition.role?i.push(o):(l(),r.push(o));return l(),r},l=(e,t,n)=>e.flatMap(e=>((e,t,n)=>{var s;let a,u=n.registry.get(e.name);if(!u){n.errors.push({...r(e),message:"not a form element"}),l(e.children,void 0,n);return}let{definition:h}=u,p=(s=h.role,t?.role==="option"||t?.role==="input"?`cannot be inside <${t.name}>, which holds no elements`:(t?.role==="choice"||t?.role==="choices")&&"option"!==s?`cannot be inside <${t.name}>, which holds only options`:void 0);p&&n.errors.push({...r(e),message:p});let{attributes:c,errors:d}=o(u,e.attributes);for(let o of d)n.errors.push({...r(e),message:o});let{label:g,value:m,...f}=c;null!=h.identity&&["label","value",...h.identity].every(o=>{let r;return null==(r=e.attributes[o])||""===r})&&n.errors.push({...r(e),message:(a=h.identity,`has nothing to show: give it one of the attributes ${["label","value",...a].map(e=>`"${e}"`).join(", ")}`)});let b=l(e.children,{name:e.name,role:h.role},n),v="option"===h.role;return{id:String(e.position),definition:h,label:"string"==typeof g?g:void 0,value:v&&"string"==typeof m?m:void 0,attributes:v||void 0===m?f:{...f,value:m},children:"group"===h.role?i(b,n):b}})(e,t,n)??[]),n=e=>{let{definition:o}=e;if("choice"===o.role||"input"===o.role&&!0===o.quick)return!0;let[r,...t]=e.children;return"group"===o.role&&null!=r&&0===t.length&&n(r)};export const parseFormBlock=(o,r)=>{let s,a,u,h,p={registry:r,errors:[]},c={name:r.group.definition.name,role:"group"},d=l((a=[s=[]],u=0,(h=new e({onopentag:(e,o)=>{let r={name:e,attributes:o,position:u+=1,children:[]};a.at(-1)?.push(r),a.push(r.children)},onclosetag:()=>{a.length>1&&a.pop()}},{xmlMode:!0,lowerCaseTags:!0,lowerCaseAttributeNames:!0,recognizeSelfClosing:!0})).write(o),h.end(),s),c,p);if(p.errors.length>0)return{ok:!1,errors:p.errors};let g=d.length>0&&d.every(e=>"option"===e.definition.role)?[t(r.choice,"choice",d)]:i(d,p),m=t(r.group,"root",g);return{ok:!0,root:m,isQuick:n(m)}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{match as t}from"ts-pattern";let e=t=>{if(""===t.trim())return;let e=Number(t);return Number.isFinite(e)?e:void 0},r=(r,{type:i})=>t(i).with("string",()=>r).with("number",()=>e(r)??r).with("integer",()=>{let t=e(r);return null!=t&&Number.isInteger(t)?t:r}).with("boolean",()=>""===r||"true"===r||"false"!==r&&r).exhaustive(),i={string:"a string",number:"a number",integer:"an integer",boolean:"true or false"},u=(t,{type:e,enum:r})=>r?`the attribute "${t}" must be one of ${r.map(t=>`"${t}"`).join(", ")}`:`the attribute "${t}" must be ${i[e]}`;export const readFormAttributes=({definition:t,attributes:e},i)=>{let n={},a=[];for(let[t,
|
|
1
|
+
import{match as t}from"ts-pattern";let e=t=>{if(""===t.trim())return;let e=Number(t);return Number.isFinite(e)?e:void 0},r=(r,{type:i})=>t(i).with("string",()=>r).with("number",()=>e(r)??r).with("integer",()=>{let t=e(r);return null!=t&&Number.isInteger(t)?t:r}).with("boolean",()=>""===r||"true"===r||"false"!==r&&r).exhaustive(),i={string:"a string",number:"a number",integer:"an integer",boolean:"true or false"},u=(t,{type:e,enum:r,pattern:u})=>r?`the attribute "${t}" must be one of ${r.map(t=>`"${t}"`).join(", ")}`:"string"===e&&null!=u?`the attribute "${t}" must match the pattern ${u}`:`the attribute "${t}" must be ${i[e]}`;export const readFormAttributes=({definition:t,attributes:e},i)=>{let n={},a=[];for(let[t,s]of Object.entries(i)){let i=e.get(t);if(!i){a.push(`the attribute "${t}" is not declared`);continue}let b=r(s,i.attribute);i.validate(b)?n[t]=b:a.push(u(t,i.attribute))}for(let e of t.required??[])e in i||a.push(`the attribute "${e}" is required`);return{attributes:n,errors:a}};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
2
|
+
import type { FormOptionProps } from './form-element-props.js';
|
|
3
|
+
type FormCardProps = FormOptionProps<AssistantBuiltInFormElementAttributes<'card'>>;
|
|
4
|
+
/**
|
|
5
|
+
* A `card`: a tile with its picture on top, then its label and description, outlined and checked
|
|
6
|
+
* while it is picked. A picture that is not a resource path or fails to load is left out.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FormCard: ({ attributes, label, value, disabled, selected, onSelect }: FormCardProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as r,jsxs as e}from"react/jsx-runtime";import{styled as i}from"@mui/material";import{useCallback as o,useState as t}from"react";import{PhxIcon as a}from"#package/ui-sdk";import{useResourceImageUrl as n}from"../resource-image/index.js";import{AssistantPanelName as d}from"../theme.js";let l=i("button",{name:d,slot:"formCard"})(({theme:{palette:r,shape:e,spacing:i}})=>({alignContent:"start",background:r.background.paper,border:`1px solid ${r.divider}`,borderRadius:e.borderRadius,color:r.text.primary,cursor:"pointer",display:"grid",flex:"1 1 140px",font:"inherit",gap:i(.25),margin:0,maxInlineSize:220,padding:i(.75),position:"relative",textAlign:"start","&:hover:not(:disabled)":{background:r.action.hover},"&:focus-visible":{outline:`2px solid ${r.primary.main}`,outlineOffset:1},"&:disabled":{color:r.text.disabled,cursor:"default"},'&[aria-pressed="true"]':{borderColor:r.primary.main,boxShadow:`inset 0 0 0 1px ${r.primary.main}`}})),s=i("img",{name:d,slot:"formCardImage"})(({theme:{shape:r,spacing:e}})=>({aspectRatio:"4 / 3",borderRadius:r.borderRadius,display:"block",inlineSize:"100%",marginBlockEnd:e(.5),objectFit:"contain"})),m=i("span",{name:d,slot:"formCardLabel"})(({theme:{typography:r}})=>({...r.body2,fontWeight:r.fontWeightMedium})),p=i("span",{name:d,slot:"formCardDescription"})(({theme:{palette:r,typography:e}})=>({...e.caption,color:r.text.secondary})),c=i("span",{name:d,slot:"formCardCheck"})(({theme:{palette:r,spacing:e}})=>({alignItems:"center",background:r.primary.main,borderRadius:"50%",color:r.primary.contrastText,display:"flex",fontSize:14,insetBlockStart:e(.5),insetInlineEnd:e(.5),justifyContent:"center",padding:2,position:"absolute"}));export const FormCard=({attributes:i,label:d,value:u,disabled:b,selected:f,onSelect:g})=>{let h=[d,u].find(Boolean),x=""===i.description?void 0:i.description,{image:y}=i,k=n()(y),[C,j]=t(),v=o(()=>{j(k)},[k]);return e(l,{type:"button","aria-label":null==h&&null==x?y:void 0,disabled:b,"aria-pressed":f,onClick:g,children:[null!=k&&k!==C&&r(s,{src:k,alt:"",loading:"lazy",onError:v}),null!=h&&r(m,{children:h}),null!=x&&r(p,{children:x}),f&&r(c,{"aria-hidden":!0,children:r(a,{name:"Check",fontSize:"inherit"})})]})};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
2
|
+
import type { FormInputProps } from './form-element-props.js';
|
|
3
|
+
type FormConfirmProps = FormInputProps<boolean, AssistantBuiltInFormElementAttributes<'confirm'>>;
|
|
4
|
+
/**
|
|
5
|
+
* A `confirm`: a yes or no question as ✓ and ✗ buttons. Its state is the pick, and it answers with
|
|
6
|
+
* the user's own words for yes and no, as the answer is their own message.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FormConfirm: ({ label, disabled, state, onChange }: FormConfirmProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{alpha as i,styled as a}from"@mui/material";import{useLocalizable as o}from"#package/react-sdk";import{PhxIcon as t}from"#package/ui-sdk";import{AssistantPanelName as n}from"../theme.js";let s={id:"sdk.assistant.form.confirm.yes",message:"Yes"},l={id:"sdk.assistant.form.confirm.no",message:"No"},d=a("div",{name:n,slot:"formConfirm"})(({theme:{palette:e,spacing:r,typography:i}})=>({...i.caption,color:e.text.secondary,display:"grid",gap:r(.75)})),m=a("div",{name:n,slot:"formConfirmButtons"})(({theme:{spacing:e}})=>({display:"flex",gap:e(.75)})),c=a("button",{name:n,slot:"formConfirmButton"})(({theme:{palette:e,spacing:r}})=>({alignItems:"center",background:e.background.paper,border:`1px solid ${e.divider}`,borderRadius:"calc(infinity * 1px)",color:e.text.primary,cursor:"pointer",display:"inline-flex",justifyContent:"center",margin:0,paddingBlock:r(.5),paddingInline:r(1.5),"&:hover:not(:disabled)":{background:e.action.hover},"&:focus-visible":{outline:`2px solid ${e.primary.main}`,outlineOffset:1},"&:disabled":{color:e.text.disabled,cursor:"default"},'&[aria-pressed="true"]':{background:i(e.primary.main,e.action.selectedOpacity),borderColor:e.primary.main}}));export const FormConfirm=({label:i,disabled:a,state:n,onChange:p})=>{let f=o(s),u=o(l);return r(d,{role:"group","aria-label":i,children:[null!=i&&e("span",{"aria-hidden":!0,children:i}),r(m,{children:[e(c,{type:"button","aria-label":f,title:f,disabled:a,"aria-pressed":!0===n,onClick:()=>p(!0,f),children:e(t,{name:"Check",fontSize:"small"})}),e(c,{type:"button","aria-label":u,title:u,disabled:a,"aria-pressed":!1===n,onClick:()=>p(!1,u),children:e(t,{name:"X",fontSize:"small"})})]})]})};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
1
2
|
import type { FormContainerProps } from './form-element-props.js';
|
|
3
|
+
type FormGroupProps = FormContainerProps<AssistantBuiltInFormElementAttributes<'group'>>;
|
|
2
4
|
/** A `group`: its children stacked under its label, which heads them. */
|
|
3
|
-
export declare const FormGroup: ({ label, children }:
|
|
5
|
+
export declare const FormGroup: ({ label, children }: FormGroupProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
2
|
+
import type { FormInputProps } from './form-element-props.js';
|
|
3
|
+
type FormNumberProps = FormInputProps<number, AssistantBuiltInFormElementAttributes<'number'>>;
|
|
4
|
+
/**
|
|
5
|
+
* A `number`: a field with its unit, and a slider beside it when both `min` and `max` are given. It
|
|
6
|
+
* stays unanswered until the user enters a number, even while the slider rests at `min`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FormNumber: ({ attributes: { value, min, max, step, unit }, label, disabled, state, onChange, }: FormNumberProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as r,jsxs as i}from"react/jsx-runtime";import{Trans as e}from"@lingui/react";import{styled as o}from"@mui/material";import{useCallback as t,useEffect as a}from"react";import{NumericalInput as m}from"#package/ui-sdk";import{AssistantPanelName as n}from"../theme.js";import{clampFormNumber as s}from"./clamp-form-number.js";let l=o("div",{name:n,slot:"formNumber"})(({theme:{palette:r,spacing:i,typography:e}})=>({alignSelf:"stretch",color:r.text.secondary,display:"grid",gap:i(.5),...e.caption})),d=(r,i)=>i?`${r} ${i}`:String(r),u=r=>""===r.trim()?null:Number(r);export const FormNumber=({attributes:{value:o,min:n,max:p,step:v,unit:c},label:f,disabled:g,state:b,onChange:h})=>{let x=void 0===o?void 0:s(o,{min:n,max:p}),j=b??x;a(()=>{void 0===b&&void 0!==x&&h(x,d(x,c))},[b,x,c,h]);let N=t(r=>h(r,d(r,c)),[h,c]),S=t(()=>{if(void 0===j)return;let r=s(j,{min:n,max:p});r!==j&&N(r)},[j,n,p,N]),k=t(r=>void 0===j?"":String(r),[j]);return i(l,{role:"group","aria-label":f,children:[null!=f&&r("span",{"aria-hidden":!0,children:f}),r(m,{value:j??n??0,min:n,max:p,unit:c,size:"small",disabled:g,withSlider:void 0!==n&&void 0!==p,sliderProps:void 0===v?void 0:{step:v},inputFieldProps:{parseValue:u,formatValue:k,invalidNumberErrorMessage:r(e,{id:"sdk.assistant.form.number.invalid",message:"Enter a number."})},onChange:N,onChanged:S})]})};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
1
2
|
import type { FormContainerProps } from './form-element-props.js';
|
|
3
|
+
type FormOptionsProps = FormContainerProps<AssistantBuiltInFormElementAttributes<'choice' | 'choices'>>;
|
|
2
4
|
/** A `choice` or `choices`: its options in a wrapping row under its label. */
|
|
3
|
-
export declare const FormOptions: ({ label, children }:
|
|
5
|
+
export declare const FormOptions: ({ label, children }: FormOptionsProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
1
2
|
import type { FormOptionProps } from './form-element-props.js';
|
|
3
|
+
type FormReplyProps = FormOptionProps<AssistantBuiltInFormElementAttributes<'reply'>>;
|
|
2
4
|
/** A `reply`: a short answer as a small pill, marked while it is picked. */
|
|
3
|
-
export declare const FormReply: ({ label, disabled, selected, onSelect }:
|
|
5
|
+
export declare const FormReply: ({ label, disabled, selected, onSelect }: FormReplyProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
2
|
+
import type { FormOptionProps } from './form-element-props.js';
|
|
3
|
+
type FormSwatchProps = FormOptionProps<AssistantBuiltInFormElementAttributes<'swatch'>>;
|
|
4
|
+
/**
|
|
5
|
+
* A `swatch`: a small square filled with its color or covered by its picture, its label in a
|
|
6
|
+
* tooltip, ringed and checked while it is picked. A picture that is not a resource path or fails to
|
|
7
|
+
* load leaves the color, or a neutral tile.
|
|
8
|
+
*/
|
|
9
|
+
export declare const FormSwatch: ({ attributes, label, value, disabled, selected, onSelect }: FormSwatchProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Tooltip as r,styled as o}from"@mui/material";import{useCallback as a,useState as t}from"react";import{PhxIcon as n}from"#package/ui-sdk";import{useResourceImageUrl as l}from"../resource-image/index.js";import{AssistantPanelName as s}from"../theme.js";let d=o("button",{name:s,slot:"formSwatch"})(({theme:{palette:e,shape:i}})=>({background:e.action.hover,blockSize:36,border:`1px solid ${e.divider}`,borderRadius:i.borderRadius,cursor:"pointer",flex:"none",inlineSize:36,margin:0,overflow:"hidden",padding:0,position:"relative","&:focus-visible":{outline:`2px solid ${e.primary.main}`,outlineOffset:3},"&:disabled":{cursor:"default",opacity:e.action.disabledOpacity},'&[aria-pressed="true"]':{boxShadow:`0 0 0 2px ${e.background.paper}, 0 0 0 4px ${e.primary.main}`}})),m=o("img",{name:s,slot:"formSwatchImage"})({blockSize:"100%",display:"block",inlineSize:"100%",objectFit:"cover"}),c=o("span",{name:s,slot:"formSwatchCheck"})(({theme:{palette:e}})=>({alignItems:"center",background:e.primary.main,borderRadius:"50%",color:e.primary.contrastText,display:"flex",fontSize:14,inset:"50% auto auto 50%",justifyContent:"center",padding:2,position:"absolute",transform:"translate(-50%, -50%)"})),p=o("span")({display:"inline-flex"});export const FormSwatch=({attributes:o,label:s,value:u,disabled:f,selected:b,onSelect:h})=>{let{color:x,image:g}=o,y=l()(g),[k,S]=t(),j=[s,u,x,g].find(Boolean),v=a(()=>{S(y)},[y]);return e(r,{title:j??"",placement:"top",children:e(p,{children:i(d,{type:"button","aria-label":j,disabled:f,"aria-pressed":b,onClick:h,style:null==x?void 0:{background:x},children:[null!=y&&y!==k&&e(m,{src:y,alt:"",loading:"lazy",onError:v}),b&&e(c,{"aria-hidden":!0,children:e(n,{name:"Check",fontSize:"inherit"})})]})})})};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { AssistantBuiltInFormElementAttributes } from '#package/domain';
|
|
1
2
|
import type { FormInputProps } from './form-element-props.js';
|
|
3
|
+
type FormTextProps = FormInputProps<string, AssistantBuiltInFormElementAttributes<'text'>>;
|
|
2
4
|
/** A `text`: a single line the user types, with its label above it. */
|
|
3
|
-
export declare const FormText: ({ attributes,
|
|
5
|
+
export declare const FormText: ({ attributes: { value, placeholder }, label, disabled, state, onChange }: FormTextProps) => import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{InputBase as t,styled as o}from"@mui/material";import{useCallback as i}from"react";import{AssistantPanelName as
|
|
1
|
+
import{jsx as e,jsxs as r}from"react/jsx-runtime";import{InputBase as t,styled as o}from"@mui/material";import{useCallback as i,useEffect as a}from"react";import{AssistantPanelName as d}from"../theme.js";let m=o("label",{name:d,slot:"formText"})(({theme:{palette:e,spacing:r,typography:t}})=>({alignSelf:"stretch",color:e.text.secondary,display:"grid",gap:r(.5),...t.caption})),l=e=>""===e.trim()?void 0:e.trim(),n=o(t,{name:d,slot:"formTextInput"})(({theme:{palette:e,spacing:r,typography:t}})=>({...t.body2,border:`1px solid ${e.divider}`,borderRadius:12,color:e.text.primary,paddingBlock:r(.75),paddingInline:r(1.5),"&.Mui-focused":{borderColor:e.primary.main},"& .MuiInputBase-input":{padding:0}}));export const FormText=({attributes:{value:t,placeholder:o},label:d,disabled:s,state:p,onChange:c})=>(a(()=>{void 0===p&&void 0!==t&&""!==t&&c(t,l(t))},[p,t,c]),r(m,{children:[d,e(n,{value:p??t??"",placeholder:o,disabled:s,onChange:i(e=>{let r=e.target.value;c(r,l(r))},[c])})]}));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** The limits a `number` keeps its value within, from its attributes. */
|
|
2
|
+
export interface FormNumberLimits {
|
|
3
|
+
readonly min?: number;
|
|
4
|
+
readonly max?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The value a `number` settles on once the user leaves the field: within `min` and `max`. The
|
|
8
|
+
* `step` is left out: it moves the slider, and a typed value between steps stays as typed.
|
|
9
|
+
*/
|
|
10
|
+
export declare const clampFormNumber: (value: number, { min, max }: FormNumberLimits) => number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const clampFormNumber=(m,{min:a,max:t})=>Math.min(t??1/0,Math.max(a??-1/0,m));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
/** Validated and coerced attributes of an element, without the built-in `label
|
|
2
|
+
/** Validated and coerced attributes of an element, without the built-in `label`: what any element gets. */
|
|
3
3
|
export type FormElementAttributes = Readonly<Record<string, unknown>>;
|
|
4
4
|
/** Props of a `group`, `choice` or `choices` element: it lays out the children the form renders for it. */
|
|
5
|
-
export interface FormContainerProps {
|
|
6
|
-
readonly attributes:
|
|
5
|
+
export interface FormContainerProps<ATTRIBUTES = FormElementAttributes> {
|
|
6
|
+
readonly attributes: ATTRIBUTES;
|
|
7
7
|
readonly label?: string;
|
|
8
8
|
readonly disabled: boolean;
|
|
9
9
|
readonly children: ReactNode;
|
|
@@ -12,23 +12,27 @@ export interface FormContainerProps {
|
|
|
12
12
|
* Props of an option. Its container decides what a pick does: in a `choice` it replaces the
|
|
13
13
|
* previous pick, in a `choices` it toggles, and in a form that asks one question it sends at once.
|
|
14
14
|
*/
|
|
15
|
-
export interface FormOptionProps {
|
|
16
|
-
readonly attributes:
|
|
15
|
+
export interface FormOptionProps<ATTRIBUTES = FormElementAttributes> {
|
|
16
|
+
readonly attributes: ATTRIBUTES;
|
|
17
17
|
readonly label?: string;
|
|
18
|
+
/** What the option answers with instead of its label, for an option that names itself by it without one. */
|
|
19
|
+
readonly value?: string;
|
|
18
20
|
readonly disabled: boolean;
|
|
19
21
|
readonly selected: boolean;
|
|
20
22
|
onSelect(): void;
|
|
21
23
|
}
|
|
22
24
|
/**
|
|
23
|
-
* Props of an input. Its state is its own: the form stores it and hands it back.
|
|
24
|
-
* text the answer shows for it, or `undefined` while there is none.
|
|
25
|
+
* Props of an input. Its state is its own: the form stores what it reports and hands it back.
|
|
26
|
+
* `answer` is the text the answer shows for it, or `undefined` while there is none. An input that
|
|
27
|
+
* starts with a `value` attribute reports its starting answer when it mounts, since an input that
|
|
28
|
+
* never reports is unanswered and only the input knows how its value reads in the answer, such as
|
|
29
|
+
* a number with its unit. A quick input, which a lone form sends on its first report, reports only
|
|
30
|
+
* what the user did.
|
|
25
31
|
*/
|
|
26
|
-
export interface FormInputProps {
|
|
27
|
-
readonly attributes:
|
|
32
|
+
export interface FormInputProps<STATE = unknown, ATTRIBUTES = FormElementAttributes> {
|
|
33
|
+
readonly attributes: ATTRIBUTES;
|
|
28
34
|
readonly label?: string;
|
|
29
|
-
/** What the field starts with. */
|
|
30
|
-
readonly value?: string;
|
|
31
35
|
readonly disabled: boolean;
|
|
32
|
-
readonly state:
|
|
33
|
-
onChange(state:
|
|
36
|
+
readonly state: STATE | undefined;
|
|
37
|
+
onChange(state: STATE, answer: string | undefined): void;
|
|
34
38
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export type { FormContainerProps, FormElementAttributes, FormInputProps, FormOptionProps, } from './form-element-props.js';
|
|
2
|
+
export { FormCard } from './FormCard.js';
|
|
3
|
+
export { FormConfirm } from './FormConfirm.js';
|
|
2
4
|
export { FormGroup } from './FormGroup.js';
|
|
3
5
|
export { FormOptions } from './FormOptions.js';
|
|
6
|
+
export { FormNumber } from './FormNumber.js';
|
|
4
7
|
export { FormReply } from './FormReply.js';
|
|
8
|
+
export { FormSwatch } from './FormSwatch.js';
|
|
5
9
|
export { FormText } from './FormText.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{FormGroup}from"./FormGroup.js";export{FormOptions}from"./FormOptions.js";export{FormReply}from"./FormReply.js";export{FormText}from"./FormText.js";
|
|
1
|
+
export{FormCard}from"./FormCard.js";export{FormConfirm}from"./FormConfirm.js";export{FormGroup}from"./FormGroup.js";export{FormOptions}from"./FormOptions.js";export{FormNumber}from"./FormNumber.js";export{FormReply}from"./FormReply.js";export{FormSwatch}from"./FormSwatch.js";export{FormText}from"./FormText.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{AssistantImage}from"./AssistantImage.js";export{
|
|
1
|
+
export{AssistantImage}from"./AssistantImage.js";export{isResourcePath}from"./resource-path.js";export{useResourceImageUrl}from"./use-resource-image-url.js";
|
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A path into the project's resources, the kind stored on `imageUrl` fields: no scheme and no host,
|
|
3
|
-
* so resolving it never leaves the resources origin. A backslash, a control character or leading
|
|
4
|
-
* whitespace is refused too, because the URL parser reads a backslash as a slash and strips the
|
|
5
|
-
* others, which would turn `\\host` or ` //host` into an address on another host.
|
|
6
|
-
*
|
|
7
|
-
* Written as a JSON Schema `pattern`, so attribute schemas can apply the same rule.
|
|
8
|
-
*/
|
|
9
|
-
export declare const RESOURCE_PATH_PATTERN: string;
|
|
10
1
|
/** True when the image source the model wrote may be requested: a path into the project's resources. */
|
|
11
2
|
export declare const isResourcePath: (src: string | undefined) => src is string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import{ASSISTANT_RESOURCE_PATH_PATTERN as e}from"#package/domain";let t=RegExp(e,"u");export const isResourcePath=e=>null!=e&&t.test(e);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export declare const hasOpenFence: (text: string) => boolean;
|
|
3
3
|
/**
|
|
4
4
|
* Makes the Markdown of a reply that is still streaming renderable as it stands, so half-written
|
|
5
|
-
* markup does not flash as raw characters: an open code fence is closed, an inline code span, a link
|
|
6
|
-
* or a table header the model has not finished is held back, and open bold text is closed.
|
|
5
|
+
* markup does not flash as raw characters: an open code fence is closed, an inline code span, a link,
|
|
6
|
+
* an alert marker or a table header the model has not finished is held back, and open bold text is closed.
|
|
7
7
|
*/
|
|
8
8
|
export declare const completeStreamedMarkdown: (text: string) => string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
let e=(e,t)=>e.split(t).length-1,t=/^\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s
|
|
2
|
-
\`\`\``;let
|
|
1
|
+
let e=(e,t)=>e.split(t).length-1,t=/^\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s*$/,l=/(^|\n) {0,3}>[ \t]*\[![a-z]*$/i,n=/(^|\n) {0,3}>[ \t]*\[![a-z]+\][ \t]*$/i;export const hasOpenFence=t=>e(t,"```")%2==1;export const completeStreamedMarkdown=s=>{var r;let a;if(hasOpenFence(s))return`${s}
|
|
2
|
+
\`\`\``;let i=s.lastIndexOf("```"),c=-1===i?"":s.slice(0,i+3),{head:$,marker:h}=(r=s.slice(c.length),null==(a=n.exec(r))?{head:r.replace(l,"$1"),marker:""}:{head:r.slice(0,a.index),marker:r.slice(a.index)}),p=(e=>{let l=e.split("\n"),n=l.length;for(;n>0&&l[n-1]?.trimStart().startsWith("|");)n-=1;let s=l.slice(n),r=s[1],a=null!=r&&s.length>2&&t.test(r);return 0===s.length||a?e:l.slice(0,n).join("\n")})((e($,"`")%2==1?$.slice(0,$.lastIndexOf("`")):$).replace(/!?\[([^\]\n]*)\](?:\([^)\n]*)?$/,"$1").replace(/!?\[[^\]\n]*$/,"")),d=e(p,"**")%2==1?`${p}**`:p;return`${c}${d}${h}`};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t}from"react/jsx-runtime";import{Badge as
|
|
1
|
+
import{jsx as t}from"react/jsx-runtime";import{Badge as o}from"@mui/material";import{memo as r,useCallback as a}from"react";import{assistantToolbarButtonSchema as s,createPhoenixLayoutElement as i}from"#package/domain";import{useLocalizable as e}from"#package/react-sdk";import{DesktopToolbar as m,PhxIcon as n,useResponsive as l}from"#package/ui-sdk";import{useAssistantPanel as c}from"../../toolbar-actions/index.js";let p={id:"sdk.assistant.toolbarButton.label",message:"Assistant"};export const AssistantToolbarButton=i({schema:s,component:r(r=>{let{icon:s,showTitle:i=!0}=r,{available:d,open:u,hasUnreadReply:k,setOpen:f}=c(),b=e(p),{isPhone:A,isTablet:g}=l(),x=a(()=>{f(!u)},[f,u]);return d?t(m.Button,{title:b,onClick:x,showTitle:i&&!A&&!g,"aria-pressed":u,sx:{'&[aria-pressed="true"]':{backgroundColor:"action.selected"}},children:t(o,{color:"primary",variant:"dot",overlap:"circular",invisible:!k,children:t(n,{name:s??(u?"CustomAiAssistantBold":"CustomAiAssistant")})})}):null})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as a}from"react/jsx-runtime";import{
|
|
1
|
+
import{jsx as e,jsxs as a}from"react/jsx-runtime";import{Trans as n}from"@lingui/react";import{Button as o,DialogActions as r,DialogContent as i,DialogTitle as l,ListItemText as t,MenuItem as m,MenuList as s,menuItemClasses as c,styled as g}from"@mui/material";import{memo as u,useCallback as d}from"react";import{createPhoenixLayoutElement as p,languageMenuActionSchema as h}from"#package/domain";import{useLocaleSwitch as x}from"#package/react-sdk";import{LocaleIcon as f}from"./language/LocaleIcon.js";import{useMenuRouting as C}from"./menu-actions/MenuRoutingContext.js";import{RoutingMenuAction as k}from"./menu-actions/RoutingMenuAction.js";let y=g(s)(({theme:{spacing:e}})=>({columnGap:e(2),display:"grid",gridTemplateColumns:"min-content auto",[`.${c.root}`]:{display:"grid",gridColumn:"1 / -1",gridTemplateColumns:"subgrid"}}));export const LanguageMenuAction=p({schema:h,component:u(()=>{let{locales:s,locale:c,setLocale:g}=x(),{close:u}=C(),p=d(e=>{g(e),u()},[g,u]);return a(k,{label:e(n,{id:"sdk.layout.hamburgerMenu.language.label",message:"Change Language"}),icon:e(f,{children:c}),children:[e(l,{children:e(n,{id:"sdk.layout.hamburgerMenu.language.dialogTitle",message:"Change Language"})}),e(i,{sx:{px:0},children:e(y,{children:s.map(n=>a(m,{onClick:()=>{p(n.locale)},children:[e(f,{sx:{color:"text.secondary"},children:n.locale}),e(t,{children:n.displayName})]},n.locale))})}),e(r,{children:e(o,{variant:"text",color:"inherit",onClick:u,children:e(n,{id:"sdk.layout.menu.language.close.label",message:"Close"})})})]})})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as a,Fragment as o}from"react/jsx-runtime";import{
|
|
1
|
+
import{jsx as e,jsxs as a,Fragment as o}from"react/jsx-runtime";import{ListItemButton as r,ListItemText as l,List as t,listItemButtonClasses as i,styled as n}from"@mui/material";import{memo as m,useCallback as c}from"react";import{createPhoenixLayoutElement as s,languageToolbarButtonSchema as p}from"#package/domain";import{useLocaleSwitch as d,useResolveLocalizable as g}from"#package/react-sdk";import{DesktopToolbar as u}from"#package/ui-sdk";import{LocaleIcon as h}from"./language/LocaleIcon.js";let x=n(t)(({theme:{spacing:e}})=>({columnGap:e(2),display:"grid",gridTemplateColumns:"min-content auto",maxBlockSize:"calc(100cqb - 50px)",overflowY:"auto",[`.${i.root}`]:{display:"grid",gridColumn:"1 / -1",gridTemplateColumns:"subgrid"}})),f={id:"sdk.toolbar.language.title",message:"Switch language"},k="language-toolbar";export const LanguageToolbarButton=s({schema:p,component:m(()=>{let{locales:t,locale:i,setLocale:n}=d(),{ref:m,handleClose:s,handleToggle:p,openedKey:b}=u.useToolbarPopper(),C=g(),y=c(()=>{p("language-toolbar")},[p]),T=c(e=>{n(e),y()},[n,y]);return a(o,{children:[e(u.Button,{ref:m,title:C(f),size:"small","aria-expanded":b===k?"true":void 0,"aria-haspopup":"menu",onClick:y,children:e(h,{sx:{minInlineSize:24},children:i})}),e(u.Popper,{placement:"top-start",anchorEl:m.current,isOpen:b===k,onClose:s,children:e(x,{children:t.map(o=>a(r,{onClick:()=>{T(o.locale)},children:[e(h,{sx:{color:"text.secondary"},children:o.locale}),e(l,{primary:o.displayName})]},o.locale))})})]})})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as
|
|
1
|
+
import{jsx as e,jsxs as n}from"react/jsx-runtime";import{Trans as m}from"@lingui/react";import{Button as r,DialogActions as s,DialogContent as t,DialogTitle as o,Stack as i}from"@mui/material";import{memo as a}from"react";import{createPhoenixLayoutElement as u,measurementsMenuActionSchema as c}from"#package/domain";import{useMeasurements as l}from"../../toolbar-actions/index.js";import{DimensionUnitSelector as d}from"./measurements/DimensionUnitSelector.js";import{MeasurementsIcon as p}from"./measurements/MeasurementsIcon.js";import{MeasurementsIndicatorsSwitch as f}from"./measurements/MeasurementsIndicatorsSwitch.js";import{useMenuRouting as h}from"./menu-actions/MenuRoutingContext.js";import{RoutingMenuAction as g}from"./menu-actions/RoutingMenuAction.js";export const MeasurementsMenuAction=u({schema:c,component:a(a=>{let{showIndicatorSwitch:u,icons:c}=a,{unit:j,hasIndicatorSwitch:x,available:M}=l({showIndicatorSwitch:u}),{close:b}=h();return M?n(g,{label:e(m,{id:"sdk.layout.menu.measurements.label",message:"Change measure"}),icon:e(p,{unit:j,icons:c}),children:[e(o,{children:e(m,{id:"sdk.layout.menu.measurements.label",message:"Change measure"})}),e(t,{children:n(i,{spacing:2,direction:"column",children:[x&&e(f,{}),e(d,{})]})}),e(s,{children:e(r,{variant:"text",color:"inherit",onClick:b,children:e(m,{id:"sdk.layout.menu.measurements.close.label",message:"Close"})})})]}):null})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as r,Fragment as s}from"react/jsx-runtime";import{Box as
|
|
1
|
+
import{jsx as e,jsxs as r,Fragment as s}from"react/jsx-runtime";import{Box as o,Stack as a}from"@mui/material";import{memo as n,useCallback as t}from"react";import{createPhoenixLayoutElement as m,measurementsToolbarButtonSchema as i}from"#package/domain";import{FrontendAnalyticsFactory as u,useAnalyticsService as p,useLocalizable as l}from"#package/react-sdk";import{DesktopToolbar as c}from"#package/ui-sdk";import{useMeasurements as d}from"../../toolbar-actions/index.js";import{DimensionUnitSelector as h}from"./measurements/DimensionUnitSelector.js";import{MeasurementsIcon as g}from"./measurements/MeasurementsIcon.js";import{MeasurementsIndicatorsSwitch as f}from"./measurements/MeasurementsIndicatorsSwitch.js";let k="measurements",j={id:"sdk.measurements",message:"Change measure"},x={id:"sdk.toolbar.measurements.change.aria",message:"open measure menu"};export const MeasurementsToolbarButton=m({schema:i,component:n(n=>{let{showIndicatorSwitch:m,icons:i}=n,{ref:M,handleClose:b,handleToggle:C,openedKey:T}=c.useToolbarPopper(),v=p(),{unit:B,hasIndicatorSwitch:I,available:P}=d({showIndicatorSwitch:m}),S=t(()=>{v.push(u.MeasurementsMenuToggled()),C(k)},[v,C]),w=t(e=>{v.push(u.MeasurementsMenuClosed()),b(e)},[v,b]),z=l(j),D=l(x);return P?r(s,{children:[e(c.Button,{ref:M,title:z,size:"small","aria-expanded":T===k?"true":void 0,"aria-label":D,"aria-haspopup":"menu",onClick:S,children:e(g,{unit:B,icons:i})}),e(c.Popper,{placement:"top-start",anchorEl:M.current,isOpen:T===k,onClose:w,children:e(o,{component:"div",sx:{p:2},children:r(a,{spacing:2,direction:"column",children:[I&&e(f,{}),e(h,{})]})})})]}):null})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as e,jsxs as r,Fragment as o}from"react/jsx-runtime";import{memo as a,useCallback as t,useState as m}from"react";import{createPhoenixLayoutElement as s,shareToolbarButtonSchema as l}from"#package/domain";import{useResolveLocalizable as n,useShareLinks as i}from"#package/react-sdk";import{DesktopToolbar as p,PhxIcon as c}from"#package/ui-sdk";import{ShareModal as d}from"./share/ShareModal.js";let h={id:"sdk.toolbar.share.open.label",message:"Share"};export const ShareToolbarButton=s({schema:l,component:a(a=>{let{icon:s}=a,[l,k]=m(!1),{available:f}=i({enabled:!1}),u=t(()=>{k(!0)},[]),g=t(()=>{k(!1)},[]),x=n();return f?r(o,{children:[e(p.Button,{title:x(h),size:"small",onClick:u,children:e(c,{name:s??"Export"})}),l&&e(d,{onClose:g})]}):null})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as t}from"react/jsx-runtime";import{
|
|
1
|
+
import{jsx as t}from"react/jsx-runtime";import{useMemo as e}from"react";import{match as i}from"ts-pattern";import{DimensionUnit as m}from"#package/domain";import{useLocalizable as r}from"#package/react-sdk";import{ToggleSelector as a}from"#package/ui-sdk";import{useMeasurements as o}from"../../../toolbar-actions/index.js";let n=r=>{let{value:o,onSelect:n}=r,l=e(()=>i(o).with(m.mm,()=>"mm").with(m.cm,()=>"cm").with(m.m,()=>"m").with(m.inch,()=>"in").with(m.feet,()=>"ft").exhaustive(),[o]),s=e(()=>i(o).with(m.mm,()=>"millimeter").with(m.cm,()=>"centimeter").with(m.m,()=>"meter").with(m.inch,()=>"inches").with(m.feet,()=>"feet").exhaustive(),[o]);return t(a.Item,{value:o,"aria-label":s,onClick:()=>n(o),children:l})},l={id:"sdk.toolbar.measurements.units.aria",message:"Measurement unit setup"};export const DimensionUnitSelector=()=>{let{units:e,unit:i,setUnit:m}=o(),s=r(l);return e.length<=1?null:t(a.Root,{"aria-label":s,value:i,exclusive:!0,columnCount:"auto-fit",sx:{maxWidth:500},children:e.map(e=>t(n,{value:e,onSelect:m},e))})};
|
package/dist/configurator/ui/phoenix-layout-elements/measurements/MeasurementsIndicatorsSwitch.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e}from"react/jsx-runtime";import{Trans as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{Trans as t}from"@lingui/react";import{Switch as r}from"@mui/material";import{useLocalizable as a}from"#package/react-sdk";import{MobileToolbar as i}from"#package/ui-sdk";import{useMeasurements as o}from"../../../toolbar-actions/index.js";let s={id:"sdk.toolbar.measurements.input.aria",message:"Switch measurements"};export const MeasurementsIndicatorsSwitch=()=>{let{indicatorsShown:m,toggleIndicators:n}=o(),c=a(s);return e(i.SectionItem,{title:e(t,{id:"sdk.toolbar.measurements.indicators.label",message:"Dimension indicators"}),content:e(r,{inputProps:{"aria-label":c},checked:m,onChange:n})})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{Button as
|
|
1
|
+
import{jsx as e,jsxs as i}from"react/jsx-runtime";import{Trans as a}from"@lingui/react";import{Button as l,DialogActions as r,DialogContent as o,DialogTitle as n,FormControlLabel as s,LinearProgress as t,Stack as d,Switch as c,TextField as h}from"@mui/material";import{memo as m,useCallback as p,useState as b}from"react";import{useResolveLocalizable as g,useShareLinks as k}from"#package/react-sdk";import{Dialog as u,PhxIcon as x}from"#package/ui-sdk";let C=i=>{let{isLinkCopied:r,onCopy:o,disabled:n}=i;return r?e(l,{variant:"muted",color:"success",startIcon:e(x,{name:"Check"}),disabled:n,onClick:o,children:e(a,{id:"sdk.toolbar.share.linkCopied.label",message:"Copied"})}):e(l,{variant:"contained",disabled:n,onClick:o,children:e(a,{id:"sdk.toolbar.share.copyLink.label",message:"Copy link"})})},v={id:"sdk.toolbar.share.loading.label",message:"loading link..."},f=({link:a,onFocus:l})=>i(d,{sx:{display:"grid","& > *":{gridArea:"1 / 1"}},children:[e(h,{value:a??"",placeholder:g()(v),hiddenLabel:!0,InputProps:{readOnly:!0},onFocus:l}),e(t,{sx:{alignSelf:"end",visibility:null==a?"visible":"hidden"}})]});export const ShareModal=m(t=>{let{onClose:h}=t,{ownerLinkAvailable:m,readLinkAvailable:g,ownerLink:x,readLink:v}=k(),[y,w]=b(!g),[T,j]=b(null),L=(y?x:v)??void 0,S=void 0!==L&&L===T,A=p(async()=>{L&&(await navigator.clipboard.writeText(L),j(L))},[L]),F=p(e=>{e.currentTarget.select()},[]),I=p(e=>{w(e.currentTarget.checked)},[]);return i(u.Root,{sx:{maxWidth:"unset",width:"min(100%, 520px)"},isOpen:!0,onClose:h,children:[e(n,{children:e(a,{id:"sdk.toolbar.share.label",message:"Share configuration"})}),e(o,{children:i(d,{sx:{gap:2},children:[e(f,{link:L,onFocus:F}),m&&g&&e(s,{control:e(c,{value:y,disabled:!L,onChange:I}),label:e(a,{id:"sdk.toolbar.share.allowEdit.label",message:"Allow the recipient to edit configuration"})})]})}),i(r,{children:[e(l,{variant:"text",color:"inherit",onClick:h,children:e(a,{id:"sdk.toolbar.share.close.label",message:"Close"})}),e(C,{isLinkCopied:S,disabled:!L,onCopy:A})]})]})});
|