@bikdotai/bik-component-library 0.0.868 → 0.0.869
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/cjs/components/bik-copilot/ControlledCopilot.js +1 -1
- package/dist/cjs/components/bik-copilot/ControlledCopilot.js.map +1 -1
- package/dist/cjs/components/bik-copilot/CopilotPanel.js +1 -1
- package/dist/cjs/components/bik-copilot/CopilotPanel.js.map +1 -1
- package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js +53 -12
- package/dist/cjs/components/bik-copilot/CopilotPanel.styled.js.map +1 -1
- package/dist/cjs/components/bik-copilot/copilotSelectionPrompt.js +2 -0
- package/dist/cjs/components/bik-copilot/copilotSelectionPrompt.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/SelectionAskPill.js +2 -0
- package/dist/cjs/components/text-selection-ask/SelectionAskPill.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/SelectionAskPill.styled.js +32 -0
- package/dist/cjs/components/text-selection-ask/SelectionAskPill.styled.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/TextSelectionAsk.js +2 -0
- package/dist/cjs/components/text-selection-ask/TextSelectionAsk.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/model.js +2 -0
- package/dist/cjs/components/text-selection-ask/model.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/selectionText.js +2 -0
- package/dist/cjs/components/text-selection-ask/selectionText.js.map +1 -0
- package/dist/cjs/components/text-selection-ask/useTextSelectionAsk.js +2 -0
- package/dist/cjs/components/text-selection-ask/useTextSelectionAsk.js.map +1 -0
- package/dist/cjs/icons/Informational/Common UI/SquaresFour.js +2 -0
- package/dist/cjs/icons/Informational/Common UI/SquaresFour.js.map +1 -0
- package/dist/cjs/icons/index.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/bik-copilot/ControlledCopilot.js +34 -30
- package/dist/esm/components/bik-copilot/ControlledCopilot.js.map +1 -1
- package/dist/esm/components/bik-copilot/CopilotPanel.js +261 -237
- package/dist/esm/components/bik-copilot/CopilotPanel.js.map +1 -1
- package/dist/esm/components/bik-copilot/CopilotPanel.styled.d.ts +8 -0
- package/dist/esm/components/bik-copilot/CopilotPanel.styled.js +69 -25
- package/dist/esm/components/bik-copilot/CopilotPanel.styled.js.map +1 -1
- package/dist/esm/components/bik-copilot/copilotSelectionPrompt.d.ts +13 -0
- package/dist/esm/components/bik-copilot/copilotSelectionPrompt.js +8 -0
- package/dist/esm/components/bik-copilot/copilotSelectionPrompt.js.map +1 -0
- package/dist/esm/components/bik-copilot/model.d.ts +19 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.d.ts +22 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.js +44 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.js.map +1 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.styled.d.ts +5 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.styled.js +37 -0
- package/dist/esm/components/text-selection-ask/SelectionAskPill.styled.js.map +1 -0
- package/dist/esm/components/text-selection-ask/TextSelectionAsk.d.ts +36 -0
- package/dist/esm/components/text-selection-ask/TextSelectionAsk.js +69 -0
- package/dist/esm/components/text-selection-ask/TextSelectionAsk.js.map +1 -0
- package/dist/esm/components/text-selection-ask/index.d.ts +7 -0
- package/dist/esm/components/text-selection-ask/model.d.ts +112 -0
- package/dist/esm/components/text-selection-ask/model.js +7 -0
- package/dist/esm/components/text-selection-ask/model.js.map +1 -0
- package/dist/esm/components/text-selection-ask/selectionText.d.ts +18 -0
- package/dist/esm/components/text-selection-ask/selectionText.js +7 -0
- package/dist/esm/components/text-selection-ask/selectionText.js.map +1 -0
- package/dist/esm/components/text-selection-ask/useTextSelectionAsk.d.ts +15 -0
- package/dist/esm/components/text-selection-ask/useTextSelectionAsk.js +53 -0
- package/dist/esm/components/text-selection-ask/useTextSelectionAsk.js.map +1 -0
- package/dist/esm/icons/Informational/Common UI/SquaresFour.d.ts +7 -0
- package/dist/esm/icons/Informational/Common UI/SquaresFour.js +33 -0
- package/dist/esm/icons/Informational/Common UI/SquaresFour.js.map +1 -0
- package/dist/esm/icons/Informational/Common UI/index.d.ts +1 -0
- package/dist/esm/icons/index.d.ts +25 -25
- package/dist/esm/icons/index.js +158 -156
- package/dist/esm/icons/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +403 -388
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -205,6 +205,18 @@ export interface CopilotShellProps {
|
|
|
205
205
|
* @default 'Loading earlier messages'
|
|
206
206
|
*/
|
|
207
207
|
historyLoadingLabel?: string;
|
|
208
|
+
/**
|
|
209
|
+
* Text quoted above the input for the next message to carry — what
|
|
210
|
+
* `TextSelectionAsk` hands over when the merchant asks about something they
|
|
211
|
+
* selected on the page. Nothing is sent until they press send.
|
|
212
|
+
*/
|
|
213
|
+
attachment?: string;
|
|
214
|
+
/**
|
|
215
|
+
* Called when the attachment should go away: the merchant removed it, or the
|
|
216
|
+
* message that carried it has been sent. The owner of `attachment` must clear
|
|
217
|
+
* it here.
|
|
218
|
+
*/
|
|
219
|
+
onAttachmentRemove?: () => void;
|
|
208
220
|
/**
|
|
209
221
|
* Controls the panel from the outside. When set, the component stops managing
|
|
210
222
|
* its own open state and `onOpenChange` must apply the change.
|
|
@@ -729,6 +741,13 @@ export interface CopilotPanelProps {
|
|
|
729
741
|
onLoadOlderMessages?: () => void;
|
|
730
742
|
historyLoadingLabel?: string;
|
|
731
743
|
inputDisabled?: boolean;
|
|
744
|
+
/**
|
|
745
|
+
* Text quoted above the input — the selection the merchant asked about. Sent
|
|
746
|
+
* as part of the next message and cleared with it.
|
|
747
|
+
*/
|
|
748
|
+
attachment?: string;
|
|
749
|
+
/** Called when the attachment's remove button is pressed. */
|
|
750
|
+
onAttachmentRemove?: () => void;
|
|
732
751
|
errorMessage?: string;
|
|
733
752
|
width?: number;
|
|
734
753
|
height?: number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { SelectionAskPillProps, SelectionRect, SelectionViewport } from './model';
|
|
3
|
+
/**
|
|
4
|
+
* Marks the pill in the DOM so a host's own outside-click or selection handling
|
|
5
|
+
* can tell it apart from the page underneath.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SELECTION_ASK_PILL_ATTRIBUTE = "data-bik-selection-ask-pill";
|
|
8
|
+
/**
|
|
9
|
+
* Puts the pill above the selection, centred on it, and flips it below when the
|
|
10
|
+
* selection is close enough to the top of the viewport that above would be off
|
|
11
|
+
* screen. Exported for the tests, which have no layout engine to check against.
|
|
12
|
+
*/
|
|
13
|
+
export declare const getSelectionPillPosition: (rect: SelectionRect, viewport: SelectionViewport) => {
|
|
14
|
+
left: number;
|
|
15
|
+
top: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The "Ask AI" pill that appears next to selected text. Purely presentational —
|
|
19
|
+
* finding the selection is `useTextSelectionAsk`'s job.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SelectionAskPill: React.FC<SelectionAskPillProps>;
|
|
22
|
+
export default SelectionAskPill;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsxs as p, jsx as I } from "react/jsx-runtime";
|
|
2
|
+
import P from "../../assets/icons/bik_ai_stars_icon.svg.js";
|
|
3
|
+
import { PillButton as L } from "./SelectionAskPill.styled.js";
|
|
4
|
+
const _ = "data-bik-selection-ask-pill", c = 8, n = 8, r = 88, f = 28, w = (t, o) => {
|
|
5
|
+
const i = t.left + t.width / 2 - r / 2, s = Math.max(
|
|
6
|
+
n,
|
|
7
|
+
o.width - r - n
|
|
8
|
+
), e = t.top - f - c, l = e < n ? t.top + t.height + c : e;
|
|
9
|
+
return {
|
|
10
|
+
left: Math.min(Math.max(i, n), s),
|
|
11
|
+
top: l
|
|
12
|
+
};
|
|
13
|
+
}, x = ({
|
|
14
|
+
anchor: t,
|
|
15
|
+
label: o = "Ask AI",
|
|
16
|
+
zIndex: i = 1202,
|
|
17
|
+
onClick: s,
|
|
18
|
+
viewport: e
|
|
19
|
+
}) => {
|
|
20
|
+
const l = e ?? (typeof window > "u" ? { width: 0 } : { width: window.innerWidth }), { left: d, top: a } = w(t.rect, l);
|
|
21
|
+
return /* @__PURE__ */ p(
|
|
22
|
+
L,
|
|
23
|
+
{
|
|
24
|
+
type: "button",
|
|
25
|
+
[_]: "true",
|
|
26
|
+
$left: d,
|
|
27
|
+
$top: a,
|
|
28
|
+
$zIndex: i,
|
|
29
|
+
onMouseDown: (h) => h.preventDefault(),
|
|
30
|
+
onClick: s,
|
|
31
|
+
"aria-label": `${o} about the selected text`,
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ I(P, { width: 14, height: 14 }),
|
|
34
|
+
o
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
_ as SELECTION_ASK_PILL_ATTRIBUTE,
|
|
41
|
+
x as SelectionAskPill,
|
|
42
|
+
w as getSelectionPillPosition
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=SelectionAskPill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionAskPill.js","sources":["../../../../src/components/text-selection-ask/SelectionAskPill.tsx"],"sourcesContent":["import AiStarsIcon from '@src/assets/icons/bik_ai_stars_icon.svg';\nimport React from 'react';\nimport {\n\tSelectionAskPillProps,\n\tSelectionRect,\n\tSelectionViewport,\n} from './model';\nimport { PillButton } from './SelectionAskPill.styled';\n\n/**\n * Marks the pill in the DOM so a host's own outside-click or selection handling\n * can tell it apart from the page underneath.\n */\nexport const SELECTION_ASK_PILL_ATTRIBUTE = 'data-bik-selection-ask-pill';\n\n/** Gap between the selection and the pill. */\nconst PILL_GAP_PX = 8;\n\n/** Smallest distance the pill keeps from the edge of the viewport. */\nconst PILL_MARGIN_PX = 8;\n\n/**\n * The design's hug size (88 x 28). Width is used for clamping only — the pill\n * hugs its label in the DOM, and estimating is enough to keep it on screen.\n * Measuring would mean rendering it off screen first and then moving it, which\n * reads as a flicker.\n */\nconst PILL_ESTIMATED_WIDTH_PX = 88;\n\nconst PILL_HEIGHT_PX = 28;\n\n/**\n * Puts the pill above the selection, centred on it, and flips it below when the\n * selection is close enough to the top of the viewport that above would be off\n * screen. Exported for the tests, which have no layout engine to check against.\n */\nexport const getSelectionPillPosition = (\n\trect: SelectionRect,\n\tviewport: SelectionViewport,\n): { left: number; top: number } => {\n\tconst centred = rect.left + rect.width / 2 - PILL_ESTIMATED_WIDTH_PX / 2;\n\tconst maxLeft = Math.max(\n\t\tPILL_MARGIN_PX,\n\t\tviewport.width - PILL_ESTIMATED_WIDTH_PX - PILL_MARGIN_PX,\n\t);\n\n\tconst above = rect.top - PILL_HEIGHT_PX - PILL_GAP_PX;\n\tconst top =\n\t\tabove < PILL_MARGIN_PX ? rect.top + rect.height + PILL_GAP_PX : above;\n\n\treturn {\n\t\tleft: Math.min(Math.max(centred, PILL_MARGIN_PX), maxLeft),\n\t\ttop,\n\t};\n};\n\n/**\n * The \"Ask AI\" pill that appears next to selected text. Purely presentational —\n * finding the selection is `useTextSelectionAsk`'s job.\n */\nexport const SelectionAskPill: React.FC<SelectionAskPillProps> = ({\n\tanchor,\n\tlabel = 'Ask AI',\n\tzIndex = 1202,\n\tonClick,\n\tviewport,\n}) => {\n\tconst resolvedViewport =\n\t\tviewport ??\n\t\t(typeof window === 'undefined'\n\t\t\t? { width: 0, height: 0 }\n\t\t\t: { width: window.innerWidth, height: window.innerHeight });\n\tconst { left, top } = getSelectionPillPosition(anchor.rect, resolvedViewport);\n\n\treturn (\n\t\t<PillButton\n\t\t\ttype=\"button\"\n\t\t\t{...{ [SELECTION_ASK_PILL_ATTRIBUTE]: 'true' }}\n\t\t\t$left={left}\n\t\t\t$top={top}\n\t\t\t$zIndex={zIndex}\n\t\t\t/* Pressing the pill would otherwise collapse the selection before the\n\t\t\t click handler runs, and there would be nothing left to hand over. */\n\t\t\tonMouseDown={(event) => event.preventDefault()}\n\t\t\tonClick={onClick}\n\t\t\taria-label={`${label} about the selected text`}\n\t\t>\n\t\t\t<AiStarsIcon width={14} height={14} />\n\t\t\t{label}\n\t\t</PillButton>\n\t);\n};\n\nexport default SelectionAskPill;\n"],"names":["SELECTION_ASK_PILL_ATTRIBUTE","PILL_GAP_PX","PILL_MARGIN_PX","PILL_ESTIMATED_WIDTH_PX","PILL_HEIGHT_PX","getSelectionPillPosition","rect","viewport","centred","maxLeft","above","top","SelectionAskPill","anchor","label","zIndex","onClick","resolvedViewport","left","jsxs","PillButton","event","jsx","AiStarsIcon"],"mappings":";;;AAaO,MAAMA,IAA+B,+BAGtCC,IAAc,GAGdC,IAAiB,GAQjBC,IAA0B,IAE1BC,IAAiB,IAOVC,IAA2B,CACvCC,GACAC,MACmC;AACnC,QAAMC,IAAUF,EAAK,OAAOA,EAAK,QAAQ,IAAIH,IAA0B,GACjEM,IAAU,KAAK;AAAA,IACpBP;AAAA,IACAK,EAAS,QAAQJ,IAA0BD;AAAA,EAAA,GAGtCQ,IAAQJ,EAAK,MAAMF,IAAiBH,GACpCU,IACLD,IAAQR,IAAiBI,EAAK,MAAMA,EAAK,SAASL,IAAcS;AAEjE,SAAO;AAAA,IACN,MAAM,KAAK,IAAI,KAAK,IAAIF,GAASN,CAAc,GAAGO,CAAO;AAAA,IACzD,KAAAE;AAAA,EAAA;AAEF,GAMaC,IAAoD,CAAC;AAAA,EACjE,QAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,QAAAC,IAAS;AAAA,EACT,SAAAC;AAAA,EACA,UAAAT;AACD,MAAM;AACL,QAAMU,IACLV,MACC,OAAO,SAAW,MAChB,EAAE,OAAO,EAAa,IACtB,EAAE,OAAO,OAAO,WAAuC,IACrD,EAAE,MAAAW,GAAM,KAAAP,EAAA,IAAQN,EAAyBQ,EAAO,MAAMI,CAAgB;AAE5E,SACC,gBAAAE;AAAA,IAACC;AAAA,IAAA;AAAA,MACA,MAAK;AAAA,MACC,CAACpB,CAA4B,GAAG;AAAA,MACtC,OAAOkB;AAAA,MACP,MAAMP;AAAA,MACN,SAASI;AAAA,MAGT,aAAa,CAACM,MAAUA,EAAM,eAAA;AAAA,MAC9B,SAAAL;AAAA,MACA,cAAY,GAAGF,CAAK;AAAA,MAEpB,UAAA;AAAA,QAAA,gBAAAQ,EAACC,GAAA,EAAY,OAAO,IAAI,QAAQ,IAAI;AAAA,QACnCT;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGJ;"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import t from "styled-components";
|
|
2
|
+
import { COLORS as r } from "../../constants/Theme.js";
|
|
3
|
+
const i = t.button`
|
|
4
|
+
position: fixed;
|
|
5
|
+
left: ${(o) => o.$left}px;
|
|
6
|
+
top: ${(o) => o.$top}px;
|
|
7
|
+
z-index: ${(o) => o.$zIndex};
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 4px;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
height: 28px;
|
|
13
|
+
padding: 4px 8px;
|
|
14
|
+
border: 1px solid ${r.stroke.brand};
|
|
15
|
+
border-radius: 4px;
|
|
16
|
+
background: ${r.surface.standard};
|
|
17
|
+
color: ${r.content.brand};
|
|
18
|
+
font-family: Inter;
|
|
19
|
+
font-size: 12px;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
line-height: 18px;
|
|
22
|
+
white-space: nowrap;
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
box-shadow: 0 4px 12px rgba(40, 3, 78, 0.16);
|
|
25
|
+
|
|
26
|
+
svg {
|
|
27
|
+
flex-shrink: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:hover {
|
|
31
|
+
background: ${r.background.brandVeryLight};
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
export {
|
|
35
|
+
i as PillButton
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=SelectionAskPill.styled.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionAskPill.styled.js","sources":["../../../../src/components/text-selection-ask/SelectionAskPill.styled.ts"],"sourcesContent":["import styled from 'styled-components';\nimport { COLORS } from '@src/constants/Theme';\n\nexport const PillButton = styled.button<{\n\t$left: number;\n\t$top: number;\n\t$zIndex: number;\n}>`\n\tposition: fixed;\n\tleft: ${(props) => props.$left}px;\n\ttop: ${(props) => props.$top}px;\n\tz-index: ${(props) => props.$zIndex};\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 4px;\n\tbox-sizing: border-box;\n\theight: 28px;\n\tpadding: 4px 8px;\n\tborder: 1px solid ${COLORS.stroke.brand};\n\tborder-radius: 4px;\n\tbackground: ${COLORS.surface.standard};\n\tcolor: ${COLORS.content.brand};\n\tfont-family: Inter;\n\tfont-size: 12px;\n\tfont-weight: 600;\n\tline-height: 18px;\n\twhite-space: nowrap;\n\tcursor: pointer;\n\tbox-shadow: 0 4px 12px rgba(40, 3, 78, 0.16);\n\n\tsvg {\n\t\tflex-shrink: 0;\n\t}\n\n\t&:hover {\n\t\tbackground: ${COLORS.background.brandVeryLight};\n\t}\n`;\n"],"names":["PillButton","styled","props","COLORS"],"mappings":";;AAGO,MAAMA,IAAaC,EAAO;AAAA;AAAA,SAMxB,CAACC,MAAUA,EAAM,KAAK;AAAA,QACvB,CAACA,MAAUA,EAAM,IAAI;AAAA,YACjB,CAACA,MAAUA,EAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAOfC,EAAO,OAAO,KAAK;AAAA;AAAA,eAEzBA,EAAO,QAAQ,QAAQ;AAAA,UAC5BA,EAAO,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAcdA,EAAO,WAAW,cAAc;AAAA;AAAA;"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { TextSelectionAskProps } from './model';
|
|
3
|
+
/**
|
|
4
|
+
* Marks everything this component renders as its own, so a selection made
|
|
5
|
+
* inside the destination — reading a copilot reply, for instance — is not
|
|
6
|
+
* mistaken for a new question about the page.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SELECTION_ASK_HOST_ATTRIBUTE = "data-bik-selection-ask-host";
|
|
9
|
+
/**
|
|
10
|
+
* Offers an "Ask AI" pill whenever the user selects text on the page, and hands
|
|
11
|
+
* that selection to wherever it should go.
|
|
12
|
+
*
|
|
13
|
+
* Mount it once, near the root of the app. Selections inside a form field, and
|
|
14
|
+
* inside whatever this renders, are ignored — the rest of the page needs no
|
|
15
|
+
* markup of its own.
|
|
16
|
+
*
|
|
17
|
+
* With `target="COPILOT_AGENT"` it renders the BIK Copilot and attaches the
|
|
18
|
+
* selection above its input, so the user types their question with the text
|
|
19
|
+
* already quoted. Nothing is sent until they press send:
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <TextSelectionAsk
|
|
23
|
+
* target={SELECTION_ASK_TARGET.COPILOT_AGENT}
|
|
24
|
+
* copilot={{ baseUrl, storeId, route, getAuthToken }}
|
|
25
|
+
* />
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* Without a target it is just the pill, and the selection arrives in `onAsk` for
|
|
29
|
+
* the host to do anything else with:
|
|
30
|
+
*
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <TextSelectionAsk onAsk={(selection) => openMyOwnAssistant(selection)} />
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare const TextSelectionAsk: React.FC<TextSelectionAskProps>;
|
|
36
|
+
export default TextSelectionAsk;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsxs as g, Fragment as B, jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { useState as h, useCallback as o } from "react";
|
|
3
|
+
import { BIKCopilot as L } from "../bik-copilot/BIKCopilot.js";
|
|
4
|
+
import { SELECTION_ASK_TARGET as R } from "./model.js";
|
|
5
|
+
import { SelectionAskPill as K } from "./SelectionAskPill.js";
|
|
6
|
+
import { useTextSelectionAsk as N } from "./useTextSelectionAsk.js";
|
|
7
|
+
const C = "data-bik-selection-ask-host", U = ({
|
|
8
|
+
enabled: O = !0,
|
|
9
|
+
target: T,
|
|
10
|
+
copilot: t,
|
|
11
|
+
onAsk: i,
|
|
12
|
+
label: d,
|
|
13
|
+
zIndex: A,
|
|
14
|
+
minLength: S,
|
|
15
|
+
shouldIgnore: m
|
|
16
|
+
}) => {
|
|
17
|
+
const [E, u] = h(null), [k, x] = h(
|
|
18
|
+
t?.defaultOpen ?? !1
|
|
19
|
+
), r = T === R.COPILOT_AGENT && !!t, s = t?.open !== void 0, l = s ? !!t?.open : k, a = o(
|
|
20
|
+
(e) => {
|
|
21
|
+
s || x(e), t?.onOpenChange?.(e);
|
|
22
|
+
},
|
|
23
|
+
[t, s]
|
|
24
|
+
), I = o(
|
|
25
|
+
(e) => {
|
|
26
|
+
const p = e instanceof HTMLElement ? e : e.parentElement;
|
|
27
|
+
return p ? p.closest(`[${C}]`) ? !0 : m?.(e) ?? !1 : !1;
|
|
28
|
+
},
|
|
29
|
+
[m]
|
|
30
|
+
), { anchor: n, clear: f } = N({
|
|
31
|
+
enabled: O,
|
|
32
|
+
minLength: S,
|
|
33
|
+
shouldIgnore: I
|
|
34
|
+
}), _ = o(() => {
|
|
35
|
+
if (!n)
|
|
36
|
+
return;
|
|
37
|
+
const { text: e } = n;
|
|
38
|
+
f(), i?.(e), r && (u(e), l || a(!0));
|
|
39
|
+
}, [n, f, l, i, a, r]), v = o(() => u(null), []);
|
|
40
|
+
return /* @__PURE__ */ g(B, { children: [
|
|
41
|
+
r && t && /* A plain wrapper: the copilot's ball and panel are `position: fixed`,
|
|
42
|
+
and a static div is not a containing block, so their placement is
|
|
43
|
+
untouched. */
|
|
44
|
+
/* @__PURE__ */ c("div", { [C]: "true", children: /* @__PURE__ */ c(
|
|
45
|
+
L,
|
|
46
|
+
{
|
|
47
|
+
...t,
|
|
48
|
+
open: l,
|
|
49
|
+
onOpenChange: a,
|
|
50
|
+
attachment: E ?? void 0,
|
|
51
|
+
onAttachmentRemove: v
|
|
52
|
+
}
|
|
53
|
+
) }),
|
|
54
|
+
n && /* @__PURE__ */ c(
|
|
55
|
+
K,
|
|
56
|
+
{
|
|
57
|
+
anchor: n,
|
|
58
|
+
label: d,
|
|
59
|
+
zIndex: A ?? (t?.zIndex ?? 1200) + 2,
|
|
60
|
+
onClick: _
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
] });
|
|
64
|
+
};
|
|
65
|
+
export {
|
|
66
|
+
C as SELECTION_ASK_HOST_ATTRIBUTE,
|
|
67
|
+
U as TextSelectionAsk
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=TextSelectionAsk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextSelectionAsk.js","sources":["../../../../src/components/text-selection-ask/TextSelectionAsk.tsx"],"sourcesContent":["import React, { useCallback, useState } from 'react';\nimport { BIKCopilot } from '../bik-copilot/BIKCopilot';\nimport { SELECTION_ASK_TARGET, TextSelectionAskProps } from './model';\nimport { SelectionAskPill } from './SelectionAskPill';\nimport { useTextSelectionAsk } from './useTextSelectionAsk';\n\n/**\n * Marks everything this component renders as its own, so a selection made\n * inside the destination — reading a copilot reply, for instance — is not\n * mistaken for a new question about the page.\n */\nexport const SELECTION_ASK_HOST_ATTRIBUTE = 'data-bik-selection-ask-host';\n\n/**\n * Offers an \"Ask AI\" pill whenever the user selects text on the page, and hands\n * that selection to wherever it should go.\n *\n * Mount it once, near the root of the app. Selections inside a form field, and\n * inside whatever this renders, are ignored — the rest of the page needs no\n * markup of its own.\n *\n * With `target=\"COPILOT_AGENT\"` it renders the BIK Copilot and attaches the\n * selection above its input, so the user types their question with the text\n * already quoted. Nothing is sent until they press send:\n *\n * ```tsx\n * <TextSelectionAsk\n * target={SELECTION_ASK_TARGET.COPILOT_AGENT}\n * copilot={{ baseUrl, storeId, route, getAuthToken }}\n * />\n * ```\n *\n * Without a target it is just the pill, and the selection arrives in `onAsk` for\n * the host to do anything else with:\n *\n * ```tsx\n * <TextSelectionAsk onAsk={(selection) => openMyOwnAssistant(selection)} />\n * ```\n */\nexport const TextSelectionAsk: React.FC<TextSelectionAskProps> = ({\n\tenabled = true,\n\ttarget,\n\tcopilot,\n\tonAsk,\n\tlabel,\n\tzIndex,\n\tminLength,\n\tshouldIgnore,\n}) => {\n\t// The selection handed to the copilot, quoted above its input until it is\n\t// sent or removed.\n\tconst [attachment, setAttachment] = useState<string | null>(null);\n\tconst [uncontrolledOpen, setUncontrolledOpen] = useState(\n\t\tcopilot?.defaultOpen ?? false,\n\t);\n\n\tconst usesCopilot =\n\t\ttarget === SELECTION_ASK_TARGET.COPILOT_AGENT && Boolean(copilot);\n\n\t// A host that drives the copilot's `open` itself keeps that control; asking\n\t// about a selection then goes through its `onOpenChange` like any other open.\n\tconst isCopilotControlled = copilot?.open !== undefined;\n\tconst isCopilotOpen = isCopilotControlled\n\t\t? Boolean(copilot?.open)\n\t\t: uncontrolledOpen;\n\n\tconst setCopilotOpen = useCallback(\n\t\t(next: boolean) => {\n\t\t\tif (!isCopilotControlled) {\n\t\t\t\tsetUncontrolledOpen(next);\n\t\t\t}\n\t\t\tcopilot?.onOpenChange?.(next);\n\t\t},\n\t\t[copilot, isCopilotControlled],\n\t);\n\n\tconst ignoreOwnSurfaces = useCallback(\n\t\t(node: Node) => {\n\t\t\tconst element = node instanceof HTMLElement ? node : node.parentElement;\n\t\t\tif (!element) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (element.closest(`[${SELECTION_ASK_HOST_ATTRIBUTE}]`)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn shouldIgnore?.(node) ?? false;\n\t\t},\n\t\t[shouldIgnore],\n\t);\n\n\tconst { anchor, clear } = useTextSelectionAsk({\n\t\tenabled,\n\t\tminLength,\n\t\tshouldIgnore: ignoreOwnSurfaces,\n\t});\n\n\tconst handleAsk = useCallback(() => {\n\t\tif (!anchor) {\n\t\t\treturn;\n\t\t}\n\t\tconst { text } = anchor;\n\t\t// Taking the highlight away is what dismisses the pill; the text now lives\n\t\t// wherever it was handed to.\n\t\tclear();\n\t\tonAsk?.(text);\n\t\tif (!usesCopilot) {\n\t\t\treturn;\n\t\t}\n\t\tsetAttachment(text);\n\t\tif (!isCopilotOpen) {\n\t\t\tsetCopilotOpen(true);\n\t\t}\n\t}, [anchor, clear, isCopilotOpen, onAsk, setCopilotOpen, usesCopilot]);\n\n\tconst handleAttachmentRemove = useCallback(() => setAttachment(null), []);\n\n\treturn (\n\t\t<>\n\t\t\t{usesCopilot && copilot && (\n\t\t\t\t/* A plain wrapper: the copilot's ball and panel are `position: fixed`,\n\t\t\t\t and a static div is not a containing block, so their placement is\n\t\t\t\t untouched. */\n\t\t\t\t<div {...{ [SELECTION_ASK_HOST_ATTRIBUTE]: 'true' }}>\n\t\t\t\t\t<BIKCopilot\n\t\t\t\t\t\t{...copilot}\n\t\t\t\t\t\topen={isCopilotOpen}\n\t\t\t\t\t\tonOpenChange={setCopilotOpen}\n\t\t\t\t\t\tattachment={attachment ?? undefined}\n\t\t\t\t\t\tonAttachmentRemove={handleAttachmentRemove}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t)}\n\n\t\t\t{anchor && (\n\t\t\t\t<SelectionAskPill\n\t\t\t\t\tanchor={anchor}\n\t\t\t\t\tlabel={label}\n\t\t\t\t\tzIndex={zIndex ?? (copilot?.zIndex ?? 1200) + 2}\n\t\t\t\t\tonClick={handleAsk}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</>\n\t);\n};\n\nexport default TextSelectionAsk;\n"],"names":["SELECTION_ASK_HOST_ATTRIBUTE","TextSelectionAsk","enabled","target","copilot","onAsk","label","zIndex","minLength","shouldIgnore","attachment","setAttachment","useState","uncontrolledOpen","setUncontrolledOpen","usesCopilot","SELECTION_ASK_TARGET","isCopilotControlled","isCopilotOpen","setCopilotOpen","useCallback","next","ignoreOwnSurfaces","node","element","anchor","clear","useTextSelectionAsk","handleAsk","text","handleAttachmentRemove","jsxs","Fragment","jsx","BIKCopilot","SelectionAskPill"],"mappings":";;;;;;AAWO,MAAMA,IAA+B,+BA4B/BC,IAAoD,CAAC;AAAA,EACjE,SAAAC,IAAU;AAAA,EACV,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,cAAAC;AACD,MAAM;AAGL,QAAM,CAACC,GAAYC,CAAa,IAAIC,EAAwB,IAAI,GAC1D,CAACC,GAAkBC,CAAmB,IAAIF;AAAA,IAC/CR,GAAS,eAAe;AAAA,EAAA,GAGnBW,IACLZ,MAAWa,EAAqB,iBAAiB,EAAQZ,GAIpDa,IAAsBb,GAAS,SAAS,QACxCc,IAAgBD,IACnB,EAAQb,GAAS,OACjBS,GAEGM,IAAiBC;AAAA,IACtB,CAACC,MAAkB;AAClB,MAAKJ,KACJH,EAAoBO,CAAI,GAEzBjB,GAAS,eAAeiB,CAAI;AAAA,IAC7B;AAAA,IACA,CAACjB,GAASa,CAAmB;AAAA,EAAA,GAGxBK,IAAoBF;AAAA,IACzB,CAACG,MAAe;AACf,YAAMC,IAAUD,aAAgB,cAAcA,IAAOA,EAAK;AAC1D,aAAKC,IAGDA,EAAQ,QAAQ,IAAIxB,CAA4B,GAAG,IAC/C,KAEDS,IAAec,CAAI,KAAK,KALvB;AAAA,IAMT;AAAA,IACA,CAACd,CAAY;AAAA,EAAA,GAGR,EAAE,QAAAgB,GAAQ,OAAAC,EAAA,IAAUC,EAAoB;AAAA,IAC7C,SAAAzB;AAAA,IACA,WAAAM;AAAA,IACA,cAAcc;AAAA,EAAA,CACd,GAEKM,IAAYR,EAAY,MAAM;AACnC,QAAI,CAACK;AACJ;AAED,UAAM,EAAE,MAAAI,MAASJ;AAKjB,IAFAC,EAAA,GACArB,IAAQwB,CAAI,GACPd,MAGLJ,EAAckB,CAAI,GACbX,KACJC,EAAe,EAAI;AAAA,EAErB,GAAG,CAACM,GAAQC,GAAOR,GAAeb,GAAOc,GAAgBJ,CAAW,CAAC,GAE/De,IAAyBV,EAAY,MAAMT,EAAc,IAAI,GAAG,CAAA,CAAE;AAExE,SACC,gBAAAoB,EAAAC,GAAA,EACE,UAAA;AAAA,IAAAjB,KAAeX;AAAA;AAAA;AAAA,IAIf,gBAAA6B,EAAC,SAAU,CAACjC,CAA4B,GAAG,QAC1C,UAAA,gBAAAiC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,GAAG9B;AAAA,QACJ,MAAMc;AAAA,QACN,cAAcC;AAAA,QACd,YAAYT,KAAc;AAAA,QAC1B,oBAAoBoB;AAAA,MAAA;AAAA,IAAA,GAEtB;AAAA,IAGAL,KACA,gBAAAQ;AAAA,MAACE;AAAA,MAAA;AAAA,QACA,QAAAV;AAAA,QACA,OAAAnB;AAAA,QACA,QAAQC,MAAWH,GAAS,UAAU,QAAQ;AAAA,QAC9C,SAASwB;AAAA,MAAA;AAAA,IAAA;AAAA,EACV,GAEF;AAEF;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { SelectionAskPill, getSelectionPillPosition } from './SelectionAskPill';
|
|
2
|
+
export { SELECTION_ASK_PILL_ATTRIBUTE } from './SelectionAskPill';
|
|
3
|
+
export { SELECTION_ASK_HOST_ATTRIBUTE, TextSelectionAsk, default as default, } from './TextSelectionAsk';
|
|
4
|
+
export { useTextSelectionAsk } from './useTextSelectionAsk';
|
|
5
|
+
export { MAX_SELECTION_LENGTH, MIN_SELECTION_LENGTH, normalizeSelection, } from './selectionText';
|
|
6
|
+
export { SELECTION_ASK_TARGET } from './model';
|
|
7
|
+
export type { SelectionAnchor, SelectionAskPillProps, SelectionAskTarget, SelectionRect, SelectionViewport, TextSelectionAskProps, UseTextSelectionAskOptions, UseTextSelectionAskResult, } from './model';
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { BIKCopilotProps } from '../bik-copilot/model';
|
|
2
|
+
/**
|
|
3
|
+
* Where an asked-about selection is sent.
|
|
4
|
+
*
|
|
5
|
+
* `COPILOT_AGENT` is the built-in destination: the component renders the BIK
|
|
6
|
+
* Copilot and hands the selection to it. Anything else a host wants to do with
|
|
7
|
+
* the text it does from `onAsk`.
|
|
8
|
+
*/
|
|
9
|
+
export declare const SELECTION_ASK_TARGET: {
|
|
10
|
+
readonly COPILOT_AGENT: "COPILOT_AGENT";
|
|
11
|
+
};
|
|
12
|
+
export type SelectionAskTarget = (typeof SELECTION_ASK_TARGET)[keyof typeof SELECTION_ASK_TARGET];
|
|
13
|
+
/** Viewport the pill is clamped to. */
|
|
14
|
+
export interface SelectionViewport {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Where a selection sits in the viewport. Plain numbers rather than a live
|
|
20
|
+
* `DOMRect`, so the pill's placement can be worked out and tested without a
|
|
21
|
+
* layout engine.
|
|
22
|
+
*/
|
|
23
|
+
export interface SelectionRect {
|
|
24
|
+
top: number;
|
|
25
|
+
left: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
}
|
|
29
|
+
/** A selection worth offering the pill for, and where to put the pill. */
|
|
30
|
+
export interface SelectionAnchor {
|
|
31
|
+
/** The selected text, whitespace-collapsed and length-capped. */
|
|
32
|
+
text: string;
|
|
33
|
+
/** Bounding box of the selection, in viewport coordinates. */
|
|
34
|
+
rect: SelectionRect;
|
|
35
|
+
}
|
|
36
|
+
/** Options of `useTextSelectionAsk`. */
|
|
37
|
+
export interface UseTextSelectionAskOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Whether selections are watched at all. `false` removes the listeners, so a
|
|
40
|
+
* host that does not want the pill pays nothing for it.
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Shortest selection that counts.
|
|
46
|
+
* @default 2
|
|
47
|
+
*/
|
|
48
|
+
minLength?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Selections inside a node this returns `true` for are ignored. Form fields
|
|
51
|
+
* are always ignored, whatever this returns.
|
|
52
|
+
*/
|
|
53
|
+
shouldIgnore?: (node: Node) => boolean;
|
|
54
|
+
}
|
|
55
|
+
/** Return value of `useTextSelectionAsk`. */
|
|
56
|
+
export interface UseTextSelectionAskResult {
|
|
57
|
+
/** The current selection, or `null` when there is nothing to offer. */
|
|
58
|
+
anchor: SelectionAnchor | null;
|
|
59
|
+
/**
|
|
60
|
+
* Drops the anchor and collapses the DOM selection, so the highlight and the
|
|
61
|
+
* pill both go away. Call it once the selection has been taken somewhere.
|
|
62
|
+
*/
|
|
63
|
+
clear: () => void;
|
|
64
|
+
}
|
|
65
|
+
/** Props of the pill offered next to a selection. */
|
|
66
|
+
export interface SelectionAskPillProps {
|
|
67
|
+
/** The selection the pill is offered for. */
|
|
68
|
+
anchor: SelectionAnchor;
|
|
69
|
+
/** @default 'Ask AI' */
|
|
70
|
+
label?: string;
|
|
71
|
+
/** Stacking order. Sits above whatever the destination renders. */
|
|
72
|
+
zIndex?: number;
|
|
73
|
+
/** Called when the pill is clicked. */
|
|
74
|
+
onClick: () => void;
|
|
75
|
+
/** Viewport the pill is clamped to. Defaults to the window's. */
|
|
76
|
+
viewport?: SelectionViewport;
|
|
77
|
+
}
|
|
78
|
+
/** Props of `TextSelectionAsk`. */
|
|
79
|
+
export interface TextSelectionAskProps extends Omit<UseTextSelectionAskOptions, 'enabled'> {
|
|
80
|
+
/**
|
|
81
|
+
* Watches the page for selections. `false` takes the pill away without
|
|
82
|
+
* unmounting the destination, so a copilot stays where it is.
|
|
83
|
+
* @default true
|
|
84
|
+
*/
|
|
85
|
+
enabled?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Where the selection goes. `COPILOT_AGENT` renders the BIK Copilot from
|
|
88
|
+
* `copilot` and attaches the selection above its input. Leave it unset to
|
|
89
|
+
* handle the text yourself in `onAsk`.
|
|
90
|
+
*/
|
|
91
|
+
target?: SelectionAskTarget;
|
|
92
|
+
/**
|
|
93
|
+
* Props for the copilot rendered when `target` is `COPILOT_AGENT`. Passed
|
|
94
|
+
* through untouched, so everything `BIKCopilot` takes works here.
|
|
95
|
+
*/
|
|
96
|
+
copilot?: BIKCopilotProps;
|
|
97
|
+
/**
|
|
98
|
+
* Called with the selected text whenever the pill is clicked, whatever the
|
|
99
|
+
* target. The only way to receive the selection when there is no target.
|
|
100
|
+
*/
|
|
101
|
+
onAsk?: (selection: string) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Label on the pill.
|
|
104
|
+
* @default 'Ask AI'
|
|
105
|
+
*/
|
|
106
|
+
label?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Stacking order of the pill. The copilot is rendered at its own `zIndex`,
|
|
109
|
+
* and the pill is placed above it.
|
|
110
|
+
*/
|
|
111
|
+
zIndex?: number;
|
|
112
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sources":["../../../../src/components/text-selection-ask/model.ts"],"sourcesContent":["import { BIKCopilotProps } from '../bik-copilot/model';\n\n/**\n * Where an asked-about selection is sent.\n *\n * `COPILOT_AGENT` is the built-in destination: the component renders the BIK\n * Copilot and hands the selection to it. Anything else a host wants to do with\n * the text it does from `onAsk`.\n */\nexport const SELECTION_ASK_TARGET = {\n\tCOPILOT_AGENT: 'COPILOT_AGENT',\n} as const;\n\nexport type SelectionAskTarget =\n\t(typeof SELECTION_ASK_TARGET)[keyof typeof SELECTION_ASK_TARGET];\n\n/** Viewport the pill is clamped to. */\nexport interface SelectionViewport {\n\twidth: number;\n\theight: number;\n}\n\n/**\n * Where a selection sits in the viewport. Plain numbers rather than a live\n * `DOMRect`, so the pill's placement can be worked out and tested without a\n * layout engine.\n */\nexport interface SelectionRect {\n\ttop: number;\n\tleft: number;\n\twidth: number;\n\theight: number;\n}\n\n/** A selection worth offering the pill for, and where to put the pill. */\nexport interface SelectionAnchor {\n\t/** The selected text, whitespace-collapsed and length-capped. */\n\ttext: string;\n\t/** Bounding box of the selection, in viewport coordinates. */\n\trect: SelectionRect;\n}\n\n/** Options of `useTextSelectionAsk`. */\nexport interface UseTextSelectionAskOptions {\n\t/**\n\t * Whether selections are watched at all. `false` removes the listeners, so a\n\t * host that does not want the pill pays nothing for it.\n\t * @default true\n\t */\n\tenabled?: boolean;\n\n\t/**\n\t * Shortest selection that counts.\n\t * @default 2\n\t */\n\tminLength?: number;\n\n\t/**\n\t * Selections inside a node this returns `true` for are ignored. Form fields\n\t * are always ignored, whatever this returns.\n\t */\n\tshouldIgnore?: (node: Node) => boolean;\n}\n\n/** Return value of `useTextSelectionAsk`. */\nexport interface UseTextSelectionAskResult {\n\t/** The current selection, or `null` when there is nothing to offer. */\n\tanchor: SelectionAnchor | null;\n\n\t/**\n\t * Drops the anchor and collapses the DOM selection, so the highlight and the\n\t * pill both go away. Call it once the selection has been taken somewhere.\n\t */\n\tclear: () => void;\n}\n\n/** Props of the pill offered next to a selection. */\nexport interface SelectionAskPillProps {\n\t/** The selection the pill is offered for. */\n\tanchor: SelectionAnchor;\n\n\t/** @default 'Ask AI' */\n\tlabel?: string;\n\n\t/** Stacking order. Sits above whatever the destination renders. */\n\tzIndex?: number;\n\n\t/** Called when the pill is clicked. */\n\tonClick: () => void;\n\n\t/** Viewport the pill is clamped to. Defaults to the window's. */\n\tviewport?: SelectionViewport;\n}\n\n/** Props of `TextSelectionAsk`. */\nexport interface TextSelectionAskProps\n\textends Omit<UseTextSelectionAskOptions, 'enabled'> {\n\t/**\n\t * Watches the page for selections. `false` takes the pill away without\n\t * unmounting the destination, so a copilot stays where it is.\n\t * @default true\n\t */\n\tenabled?: boolean;\n\n\t/**\n\t * Where the selection goes. `COPILOT_AGENT` renders the BIK Copilot from\n\t * `copilot` and attaches the selection above its input. Leave it unset to\n\t * handle the text yourself in `onAsk`.\n\t */\n\ttarget?: SelectionAskTarget;\n\n\t/**\n\t * Props for the copilot rendered when `target` is `COPILOT_AGENT`. Passed\n\t * through untouched, so everything `BIKCopilot` takes works here.\n\t */\n\tcopilot?: BIKCopilotProps;\n\n\t/**\n\t * Called with the selected text whenever the pill is clicked, whatever the\n\t * target. The only way to receive the selection when there is no target.\n\t */\n\tonAsk?: (selection: string) => void;\n\n\t/**\n\t * Label on the pill.\n\t * @default 'Ask AI'\n\t */\n\tlabel?: string;\n\n\t/**\n\t * Stacking order of the pill. The copilot is rendered at its own `zIndex`,\n\t * and the pill is placed above it.\n\t */\n\tzIndex?: number;\n}\n"],"names":["SELECTION_ASK_TARGET"],"mappings":"AASO,MAAMA,IAAuB;AAAA,EACnC,eAAe;AAChB;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shortest selection the pill is offered for. A stray click that lands one
|
|
3
|
+
* character inside a word is not a question anybody meant to ask.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MIN_SELECTION_LENGTH = 2;
|
|
6
|
+
/**
|
|
7
|
+
* Longest selection carried out of the page. Consumers put the text into a
|
|
8
|
+
* prompt, so an accidental select-all must not become the whole request.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MAX_SELECTION_LENGTH = 1000;
|
|
11
|
+
/**
|
|
12
|
+
* Collapses the whitespace a DOM selection picks up and caps its length.
|
|
13
|
+
*
|
|
14
|
+
* Dragging across a table or a stat card pulls in the newlines and indentation
|
|
15
|
+
* between the cells, so the raw string is unusable both as a chip label and as
|
|
16
|
+
* part of a prompt.
|
|
17
|
+
*/
|
|
18
|
+
export declare const normalizeSelection: (text: string) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectionText.js","sources":["../../../../src/components/text-selection-ask/selectionText.ts"],"sourcesContent":["/**\n * Shortest selection the pill is offered for. A stray click that lands one\n * character inside a word is not a question anybody meant to ask.\n */\nexport const MIN_SELECTION_LENGTH = 2;\n\n/**\n * Longest selection carried out of the page. Consumers put the text into a\n * prompt, so an accidental select-all must not become the whole request.\n */\nexport const MAX_SELECTION_LENGTH = 1000;\n\n/**\n * Collapses the whitespace a DOM selection picks up and caps its length.\n *\n * Dragging across a table or a stat card pulls in the newlines and indentation\n * between the cells, so the raw string is unusable both as a chip label and as\n * part of a prompt.\n */\nexport const normalizeSelection = (text: string): string =>\n\ttext.replace(/\\s+/g, ' ').trim().slice(0, MAX_SELECTION_LENGTH);\n"],"names":["MIN_SELECTION_LENGTH","MAX_SELECTION_LENGTH","normalizeSelection","text"],"mappings":"AAIO,MAAMA,IAAuB,GAMvBC,IAAuB,KASvBC,IAAqB,CAACC,MAClCA,EAAK,QAAQ,QAAQ,GAAG,EAAE,KAAA,EAAO,MAAM,GAAG,GAAoB;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { UseTextSelectionAskOptions, UseTextSelectionAskResult } from './model';
|
|
2
|
+
/**
|
|
3
|
+
* Watches the page for a text selection worth asking about.
|
|
4
|
+
*
|
|
5
|
+
* Selections are read on pointer and key release rather than from
|
|
6
|
+
* `selectionchange` alone: that event fires on every mouse move of a drag, so
|
|
7
|
+
* anchoring to it would have the pill chasing the cursor. `selectionchange` is
|
|
8
|
+
* still listened to, for the other direction — a click that collapses the
|
|
9
|
+
* selection has to take the pill away immediately.
|
|
10
|
+
*
|
|
11
|
+
* The anchor's rect is in viewport coordinates and is recomputed on scroll and
|
|
12
|
+
* resize, so a `position: fixed` pill keeps up with the text it points at.
|
|
13
|
+
*/
|
|
14
|
+
export declare const useTextSelectionAsk: ({ enabled, minLength, shouldIgnore, }?: UseTextSelectionAskOptions) => UseTextSelectionAskResult;
|
|
15
|
+
export default useTextSelectionAsk;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useState as E, useCallback as g, useEffect as h } from "react";
|
|
2
|
+
import { MIN_SELECTION_LENGTH as v, normalizeSelection as w } from "./selectionText.js";
|
|
3
|
+
const p = (t) => t ? t instanceof HTMLElement ? t : t.parentElement : null, L = (t) => {
|
|
4
|
+
const o = p(t);
|
|
5
|
+
return o ? o.isContentEditable ? !0 : !!o.closest("input, textarea, select, [contenteditable]") : !1;
|
|
6
|
+
}, A = ({
|
|
7
|
+
enabled: t = !0,
|
|
8
|
+
minLength: o = v,
|
|
9
|
+
shouldIgnore: s
|
|
10
|
+
} = {}) => {
|
|
11
|
+
const [d, i] = E(null), m = g(() => {
|
|
12
|
+
i(null), window.getSelection()?.removeAllRanges();
|
|
13
|
+
}, []);
|
|
14
|
+
return h(() => {
|
|
15
|
+
if (!t) {
|
|
16
|
+
i(null);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const f = () => {
|
|
20
|
+
const e = window.getSelection();
|
|
21
|
+
if (!e || e.isCollapsed || e.rangeCount === 0)
|
|
22
|
+
return null;
|
|
23
|
+
const a = w(e.toString());
|
|
24
|
+
if (a.length < o)
|
|
25
|
+
return null;
|
|
26
|
+
const l = e.getRangeAt(0);
|
|
27
|
+
if (L(l.commonAncestorContainer) || s?.(l.commonAncestorContainer))
|
|
28
|
+
return null;
|
|
29
|
+
const r = l.getBoundingClientRect();
|
|
30
|
+
return r.width === 0 && r.height === 0 ? null : {
|
|
31
|
+
text: a,
|
|
32
|
+
rect: {
|
|
33
|
+
top: r.top,
|
|
34
|
+
left: r.left,
|
|
35
|
+
width: r.width,
|
|
36
|
+
height: r.height
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}, n = () => i(f()), c = () => {
|
|
40
|
+
const e = window.getSelection();
|
|
41
|
+
(!e || e.isCollapsed) && i(null);
|
|
42
|
+
}, u = (e) => {
|
|
43
|
+
(e.shiftKey || e.key === "Shift") && n();
|
|
44
|
+
};
|
|
45
|
+
return document.addEventListener("pointerup", n), document.addEventListener("keyup", u), document.addEventListener("selectionchange", c), window.addEventListener("scroll", n, !0), window.addEventListener("resize", n), () => {
|
|
46
|
+
document.removeEventListener("pointerup", n), document.removeEventListener("keyup", u), document.removeEventListener("selectionchange", c), window.removeEventListener("scroll", n, !0), window.removeEventListener("resize", n);
|
|
47
|
+
};
|
|
48
|
+
}, [t, o, s]), { anchor: d, clear: m };
|
|
49
|
+
};
|
|
50
|
+
export {
|
|
51
|
+
A as useTextSelectionAsk
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=useTextSelectionAsk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTextSelectionAsk.js","sources":["../../../../src/components/text-selection-ask/useTextSelectionAsk.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport {\n\tSelectionAnchor,\n\tUseTextSelectionAskOptions,\n\tUseTextSelectionAskResult,\n} from './model';\nimport { MIN_SELECTION_LENGTH, normalizeSelection } from './selectionText';\n\nconst asElement = (node: Node | null): HTMLElement | null => {\n\tif (!node) {\n\t\treturn null;\n\t}\n\treturn node instanceof HTMLElement ? node : node.parentElement;\n};\n\n/**\n * Whether the selection is being made inside something the user is typing in.\n * Text they are editing is not text they are asking about, and a pill over a\n * form field would fight the field's own selection handles.\n */\nconst isEditableTarget = (node: Node | null): boolean => {\n\tconst element = asElement(node);\n\tif (!element) {\n\t\treturn false;\n\t}\n\tif (element.isContentEditable) {\n\t\treturn true;\n\t}\n\treturn Boolean(element.closest('input, textarea, select, [contenteditable]'));\n};\n\n/**\n * Watches the page for a text selection worth asking about.\n *\n * Selections are read on pointer and key release rather than from\n * `selectionchange` alone: that event fires on every mouse move of a drag, so\n * anchoring to it would have the pill chasing the cursor. `selectionchange` is\n * still listened to, for the other direction — a click that collapses the\n * selection has to take the pill away immediately.\n *\n * The anchor's rect is in viewport coordinates and is recomputed on scroll and\n * resize, so a `position: fixed` pill keeps up with the text it points at.\n */\nexport const useTextSelectionAsk = ({\n\tenabled = true,\n\tminLength = MIN_SELECTION_LENGTH,\n\tshouldIgnore,\n}: UseTextSelectionAskOptions = {}): UseTextSelectionAskResult => {\n\tconst [anchor, setAnchor] = useState<SelectionAnchor | null>(null);\n\n\tconst clear = useCallback(() => {\n\t\tsetAnchor(null);\n\t\t// Collapsing the range as well is what stops the pill coming back: the\n\t\t// selection it was offered for no longer exists, so nothing re-reads it.\n\t\twindow.getSelection()?.removeAllRanges();\n\t}, []);\n\n\tuseEffect(() => {\n\t\tif (!enabled) {\n\t\t\t// Leaving a stale anchor behind would keep a pill on screen that the\n\t\t\t// host has just turned off.\n\t\t\tsetAnchor(null);\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst readSelection = (): SelectionAnchor | null => {\n\t\t\tconst selection = window.getSelection();\n\t\t\tif (!selection || selection.isCollapsed || selection.rangeCount === 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst text = normalizeSelection(selection.toString());\n\t\t\tif (text.length < minLength) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst range = selection.getRangeAt(0);\n\t\t\tif (\n\t\t\t\tisEditableTarget(range.commonAncestorContainer) ||\n\t\t\t\tshouldIgnore?.(range.commonAncestorContainer)\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst rect = range.getBoundingClientRect();\n\t\t\t// A range inside a hidden or zero-sized node has nowhere to put a pill.\n\t\t\tif (rect.width === 0 && rect.height === 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\ttext,\n\t\t\t\trect: {\n\t\t\t\t\ttop: rect.top,\n\t\t\t\t\tleft: rect.left,\n\t\t\t\t\twidth: rect.width,\n\t\t\t\t\theight: rect.height,\n\t\t\t\t},\n\t\t\t};\n\t\t};\n\n\t\tconst evaluate = () => setAnchor(readSelection());\n\n\t\tconst handleSelectionChange = () => {\n\t\t\tconst selection = window.getSelection();\n\t\t\tif (!selection || selection.isCollapsed) {\n\t\t\t\tsetAnchor(null);\n\t\t\t}\n\t\t};\n\n\t\tconst handleKeyUp = (event: KeyboardEvent) => {\n\t\t\t// Only the gestures that extend a selection; every other keystroke\n\t\t\t// would just re-read the same range.\n\t\t\tif (event.shiftKey || event.key === 'Shift') {\n\t\t\t\tevaluate();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener('pointerup', evaluate);\n\t\tdocument.addEventListener('keyup', handleKeyUp);\n\t\tdocument.addEventListener('selectionchange', handleSelectionChange);\n\t\t// Capture, so a selection inside a scrollable table is followed too and not\n\t\t// only the page's own scrolling.\n\t\twindow.addEventListener('scroll', evaluate, true);\n\t\twindow.addEventListener('resize', evaluate);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('pointerup', evaluate);\n\t\t\tdocument.removeEventListener('keyup', handleKeyUp);\n\t\t\tdocument.removeEventListener('selectionchange', handleSelectionChange);\n\t\t\twindow.removeEventListener('scroll', evaluate, true);\n\t\t\twindow.removeEventListener('resize', evaluate);\n\t\t};\n\t}, [enabled, minLength, shouldIgnore]);\n\n\treturn { anchor, clear };\n};\n\nexport default useTextSelectionAsk;\n"],"names":["asElement","node","isEditableTarget","element","useTextSelectionAsk","enabled","minLength","MIN_SELECTION_LENGTH","shouldIgnore","anchor","setAnchor","useState","clear","useCallback","useEffect","readSelection","selection","text","normalizeSelection","range","rect","evaluate","handleSelectionChange","handleKeyUp","event"],"mappings":";;AAQA,MAAMA,IAAY,CAACC,MACbA,IAGEA,aAAgB,cAAcA,IAAOA,EAAK,gBAFzC,MAUHC,IAAmB,CAACD,MAA+B;AACxD,QAAME,IAAUH,EAAUC,CAAI;AAC9B,SAAKE,IAGDA,EAAQ,oBACJ,KAED,EAAQA,EAAQ,QAAQ,4CAA4C,IALnE;AAMT,GAcaC,IAAsB,CAAC;AAAA,EACnC,SAAAC,IAAU;AAAA,EACV,WAAAC,IAAYC;AAAA,EACZ,cAAAC;AACD,IAAgC,OAAkC;AACjE,QAAM,CAACC,GAAQC,CAAS,IAAIC,EAAiC,IAAI,GAE3DC,IAAQC,EAAY,MAAM;AAC/B,IAAAH,EAAU,IAAI,GAGd,OAAO,aAAA,GAAgB,gBAAA;AAAA,EACxB,GAAG,CAAA,CAAE;AAEL,SAAAI,EAAU,MAAM;AACf,QAAI,CAACT,GAAS;AAGb,MAAAK,EAAU,IAAI;AACd;AAAA,IACD;AAEA,UAAMK,IAAgB,MAA8B;AACnD,YAAMC,IAAY,OAAO,aAAA;AACzB,UAAI,CAACA,KAAaA,EAAU,eAAeA,EAAU,eAAe;AACnE,eAAO;AAGR,YAAMC,IAAOC,EAAmBF,EAAU,SAAA,CAAU;AACpD,UAAIC,EAAK,SAASX;AACjB,eAAO;AAGR,YAAMa,IAAQH,EAAU,WAAW,CAAC;AACpC,UACCd,EAAiBiB,EAAM,uBAAuB,KAC9CX,IAAeW,EAAM,uBAAuB;AAE5C,eAAO;AAGR,YAAMC,IAAOD,EAAM,sBAAA;AAEnB,aAAIC,EAAK,UAAU,KAAKA,EAAK,WAAW,IAChC,OAGD;AAAA,QACN,MAAAH;AAAA,QACA,MAAM;AAAA,UACL,KAAKG,EAAK;AAAA,UACV,MAAMA,EAAK;AAAA,UACX,OAAOA,EAAK;AAAA,UACZ,QAAQA,EAAK;AAAA,QAAA;AAAA,MACd;AAAA,IAEF,GAEMC,IAAW,MAAMX,EAAUK,GAAe,GAE1CO,IAAwB,MAAM;AACnC,YAAMN,IAAY,OAAO,aAAA;AACzB,OAAI,CAACA,KAAaA,EAAU,gBAC3BN,EAAU,IAAI;AAAA,IAEhB,GAEMa,IAAc,CAACC,MAAyB;AAG7C,OAAIA,EAAM,YAAYA,EAAM,QAAQ,YACnCH,EAAA;AAAA,IAEF;AAEA,oBAAS,iBAAiB,aAAaA,CAAQ,GAC/C,SAAS,iBAAiB,SAASE,CAAW,GAC9C,SAAS,iBAAiB,mBAAmBD,CAAqB,GAGlE,OAAO,iBAAiB,UAAUD,GAAU,EAAI,GAChD,OAAO,iBAAiB,UAAUA,CAAQ,GAEnC,MAAM;AACZ,eAAS,oBAAoB,aAAaA,CAAQ,GAClD,SAAS,oBAAoB,SAASE,CAAW,GACjD,SAAS,oBAAoB,mBAAmBD,CAAqB,GACrE,OAAO,oBAAoB,UAAUD,GAAU,EAAI,GACnD,OAAO,oBAAoB,UAAUA,CAAQ;AAAA,IAC9C;AAAA,EACD,GAAG,CAAChB,GAASC,GAAWE,CAAY,CAAC,GAE9B,EAAE,QAAAC,GAAQ,OAAAG,EAAA;AAClB;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SVGProps } from 'react';
|
|
2
|
+
interface Props extends SVGProps<SVGSVGElement> {
|
|
3
|
+
size?: number | string;
|
|
4
|
+
color?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const SvgSquaresFour: ({ size, color, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default SvgSquaresFour;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
2
|
+
const e = ({
|
|
3
|
+
size: C = 24,
|
|
4
|
+
color: H = "currentColor",
|
|
5
|
+
...V
|
|
6
|
+
}) => {
|
|
7
|
+
const o = {
|
|
8
|
+
width: C,
|
|
9
|
+
height: C,
|
|
10
|
+
color: H,
|
|
11
|
+
...V
|
|
12
|
+
};
|
|
13
|
+
return /* @__PURE__ */ r(
|
|
14
|
+
"svg",
|
|
15
|
+
{
|
|
16
|
+
viewBox: "0 0 16 16",
|
|
17
|
+
fill: "none",
|
|
18
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
19
|
+
...o,
|
|
20
|
+
children: /* @__PURE__ */ r(
|
|
21
|
+
"path",
|
|
22
|
+
{
|
|
23
|
+
d: "M6.36364 2H3.09091C2.80158 2 2.5241 2.11493 2.31952 2.31952C2.11493 2.5241 2 2.80158 2 3.09091V6.36364C2 6.65296 2.11493 6.93044 2.31952 7.13503C2.5241 7.33961 2.80158 7.45455 3.09091 7.45455H6.36364C6.65296 7.45455 6.93044 7.33961 7.13503 7.13503C7.33961 6.93044 7.45455 6.65296 7.45455 6.36364V3.09091C7.45455 2.80158 7.33961 2.5241 7.13503 2.31952C6.93044 2.11493 6.65296 2 6.36364 2ZM6.36364 6.36364H3.09091V3.09091H6.36364V6.36364ZM12.9091 2H9.63636C9.34704 2 9.06956 2.11493 8.86497 2.31952C8.66039 2.5241 8.54545 2.80158 8.54545 3.09091V6.36364C8.54545 6.65296 8.66039 6.93044 8.86497 7.13503C9.06956 7.33961 9.34704 7.45455 9.63636 7.45455H12.9091C13.1984 7.45455 13.4759 7.33961 13.6805 7.13503C13.8851 6.93044 14 6.65296 14 6.36364V3.09091C14 2.80158 13.8851 2.5241 13.6805 2.31952C13.4759 2.11493 13.1984 2 12.9091 2ZM12.9091 6.36364H9.63636V3.09091H12.9091V6.36364ZM6.36364 8.54545H3.09091C2.80158 8.54545 2.5241 8.66039 2.31952 8.86497C2.11493 9.06956 2 9.34704 2 9.63636V12.9091C2 13.1984 2.11493 13.4759 2.31952 13.6805C2.5241 13.8851 2.80158 14 3.09091 14H6.36364C6.65296 14 6.93044 13.8851 7.13503 13.6805C7.33961 13.4759 7.45455 13.1984 7.45455 12.9091V9.63636C7.45455 9.34704 7.33961 9.06956 7.13503 8.86497C6.93044 8.66039 6.65296 8.54545 6.36364 8.54545ZM6.36364 12.9091H3.09091V9.63636H6.36364V12.9091ZM12.9091 8.54545H9.63636C9.34704 8.54545 9.06956 8.66039 8.86497 8.86497C8.66039 9.06956 8.54545 9.34704 8.54545 9.63636V12.9091C8.54545 13.1984 8.66039 13.4759 8.86497 13.6805C9.06956 13.8851 9.34704 14 9.63636 14H12.9091C13.1984 14 13.4759 13.8851 13.6805 13.6805C13.8851 13.4759 14 13.1984 14 12.9091V9.63636C14 9.34704 13.8851 9.06956 13.6805 8.86497C13.4759 8.66039 13.1984 8.54545 12.9091 8.54545ZM12.9091 12.9091H9.63636V9.63636H12.9091V12.9091Z",
|
|
24
|
+
fill: "currentColor"
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
e as default
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=SquaresFour.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SquaresFour.js","sources":["../../../../../src/icons/Informational/Common UI/SquaresFour.tsx"],"sourcesContent":["import type { SVGProps } from 'react';\n\ninterface Props extends SVGProps<SVGSVGElement> {\n\tsize?: number | string;\n\tcolor?: string;\n}\nconst SvgSquaresFour = ({\n\tsize = 24,\n\tcolor = 'currentColor',\n\t...rest\n}: Props) => {\n\tconst props = {\n\t\twidth: size,\n\t\theight: size,\n\t\tcolor,\n\t\t...rest,\n\t};\n\treturn (\n\t\t<svg\n\t\t\tviewBox=\"0 0 16 16\"\n\t\t\tfill=\"none\"\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t{...props}\n\t\t>\n\t\t\t<path\n\t\t\t\td=\"M6.36364 2H3.09091C2.80158 2 2.5241 2.11493 2.31952 2.31952C2.11493 2.5241 2 2.80158 2 3.09091V6.36364C2 6.65296 2.11493 6.93044 2.31952 7.13503C2.5241 7.33961 2.80158 7.45455 3.09091 7.45455H6.36364C6.65296 7.45455 6.93044 7.33961 7.13503 7.13503C7.33961 6.93044 7.45455 6.65296 7.45455 6.36364V3.09091C7.45455 2.80158 7.33961 2.5241 7.13503 2.31952C6.93044 2.11493 6.65296 2 6.36364 2ZM6.36364 6.36364H3.09091V3.09091H6.36364V6.36364ZM12.9091 2H9.63636C9.34704 2 9.06956 2.11493 8.86497 2.31952C8.66039 2.5241 8.54545 2.80158 8.54545 3.09091V6.36364C8.54545 6.65296 8.66039 6.93044 8.86497 7.13503C9.06956 7.33961 9.34704 7.45455 9.63636 7.45455H12.9091C13.1984 7.45455 13.4759 7.33961 13.6805 7.13503C13.8851 6.93044 14 6.65296 14 6.36364V3.09091C14 2.80158 13.8851 2.5241 13.6805 2.31952C13.4759 2.11493 13.1984 2 12.9091 2ZM12.9091 6.36364H9.63636V3.09091H12.9091V6.36364ZM6.36364 8.54545H3.09091C2.80158 8.54545 2.5241 8.66039 2.31952 8.86497C2.11493 9.06956 2 9.34704 2 9.63636V12.9091C2 13.1984 2.11493 13.4759 2.31952 13.6805C2.5241 13.8851 2.80158 14 3.09091 14H6.36364C6.65296 14 6.93044 13.8851 7.13503 13.6805C7.33961 13.4759 7.45455 13.1984 7.45455 12.9091V9.63636C7.45455 9.34704 7.33961 9.06956 7.13503 8.86497C6.93044 8.66039 6.65296 8.54545 6.36364 8.54545ZM6.36364 12.9091H3.09091V9.63636H6.36364V12.9091ZM12.9091 8.54545H9.63636C9.34704 8.54545 9.06956 8.66039 8.86497 8.86497C8.66039 9.06956 8.54545 9.34704 8.54545 9.63636V12.9091C8.54545 13.1984 8.66039 13.4759 8.86497 13.6805C9.06956 13.8851 9.34704 14 9.63636 14H12.9091C13.1984 14 13.4759 13.8851 13.6805 13.6805C13.8851 13.4759 14 13.1984 14 12.9091V9.63636C14 9.34704 13.8851 9.06956 13.6805 8.86497C13.4759 8.66039 13.1984 8.54545 12.9091 8.54545ZM12.9091 12.9091H9.63636V9.63636H12.9091V12.9091Z\"\n\t\t\t\tfill=\"currentColor\"\n\t\t\t/>\n\t\t</svg>\n\t);\n};\nexport default SvgSquaresFour;\n"],"names":["SvgSquaresFour","size","color","rest","props","jsx"],"mappings":";AAMA,MAAMA,IAAiB,CAAC;AAAA,EACvB,MAAAC,IAAO;AAAA,EACP,OAAAC,IAAQ;AAAA,EACR,GAAGC;AACJ,MAAa;AACZ,QAAMC,IAAQ;AAAA,IACb,OAAOH;AAAA,IACP,QAAQA;AAAA,IACR,OAAAC;AAAA,IACA,GAAGC;AAAA,EAAA;AAEJ,SACC,gBAAAE;AAAA,IAAC;AAAA,IAAA;AAAA,MACA,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAM;AAAA,MACL,GAAGD;AAAA,MAEJ,UAAA,gBAAAC;AAAA,QAAC;AAAA,QAAA;AAAA,UACA,GAAE;AAAA,UACF,MAAK;AAAA,QAAA;AAAA,MAAA;AAAA,IACN;AAAA,EAAA;AAGH;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as Shield } from './Shield';
|
|
2
2
|
export { default as ShieldOutline } from './ShieldOutline';
|
|
3
|
+
export { default as SquaresFour } from './SquaresFour';
|
|
3
4
|
export { default as Bell } from './Bell';
|
|
4
5
|
export { default as BellSync } from './BellSync';
|
|
5
6
|
export { default as Bulb } from './Bulb';
|