@luscii-healthtech/web-ui 58.2.5 → 58.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,99 @@
1
+ import { type FC } from "react";
2
+ /**
3
+ * The kind of instrument, which selects the leading icon. Overridden by
4
+ * `ExclamationMarkIcon` when `state` is `"error"`.
5
+ */
6
+ export type InstrumentType = "info" | "questionnaire" | "numeric" | "document" | "contact" | "other" | "scripted" | "sum";
7
+ type BaseProps = {
8
+ /** Selects the leading icon. */
9
+ type: InstrumentType;
10
+ /**
11
+ * Name of the instrument. Truncates with an ellipsis in the `detailed`
12
+ * variant; in `compact` it is the pill label, and is replaced by
13
+ * `errorMessage` when `state` is `"error"`.
14
+ */
15
+ title: string;
16
+ /**
17
+ * First cell of the meta row, e.g. `"Lesson"`. `detailed` only, and not
18
+ * rendered when `state` is `"error"` — the error message takes its place.
19
+ */
20
+ category?: string;
21
+ /**
22
+ * Second cell of the meta row, e.g. `"Comments ON"`, separated from
23
+ * `category` by a vertical rule. Rendered only alongside `category`.
24
+ * `detailed` only, and replaced by the error message in the error state.
25
+ */
26
+ meta?: string;
27
+ /**
28
+ * Instrument identifier, e.g. `"Id-30ry3-7240"`. Rendered as a bordered
29
+ * tag beneath the meta row. `detailed` only; omitted when absent.
30
+ */
31
+ id?: string;
32
+ /**
33
+ * Number shown in the trailing tag — how many times the instrument is used.
34
+ * `detailed` only; omitted when absent. `0` renders, it is not treated as
35
+ * empty.
36
+ */
37
+ count?: number;
38
+ /**
39
+ * `"compact"` is an inline pill of icon plus label, for listing
40
+ * instruments inside an action card. `"detailed"` is a full-width row with
41
+ * a title, meta row and tags.
42
+ *
43
+ * @default "compact"
44
+ */
45
+ variant?: "compact" | "detailed";
46
+ /** Merged onto the root element. */
47
+ className?: string;
48
+ };
49
+ /**
50
+ * `errorMessage` is what the error state renders — it replaces the label in
51
+ * the compact variant and the meta row in the detailed variant. Requiring it
52
+ * alongside `state="error"` makes the empty-error-label state impossible to
53
+ * express, rather than guarding against it at runtime.
54
+ *
55
+ * In the error state the icon becomes `ExclamationMarkIcon` and the icon,
56
+ * title and message all take the error colour.
57
+ *
58
+ * @default state "default"
59
+ */
60
+ type StateProps = {
61
+ state?: "default";
62
+ errorMessage?: never;
63
+ } | {
64
+ state: "error";
65
+ errorMessage: string;
66
+ };
67
+ export type Props = BaseProps & StateProps;
68
+ /**
69
+ * Renders a single instrument belonging to an action.
70
+ *
71
+ * Use `variant="compact"` for the inline pills listed on an `ActionCard`, and
72
+ * `variant="detailed"` for the full rows in `ActionCardDetailed`. Both of
73
+ * those consumers force the variant, so it is not part of the props they
74
+ * accept.
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * <InstrumentCard type="info" title="How to stop smoking" />
79
+ *
80
+ * <InstrumentCard
81
+ * variant="detailed"
82
+ * type="questionnaire"
83
+ * title="Daily health questionnaire"
84
+ * category="Questionnaire"
85
+ * meta="Comments ON"
86
+ * id="Id-30ry3-7240"
87
+ * count={4}
88
+ * />
89
+ *
90
+ * <InstrumentCard
91
+ * type="other"
92
+ * title="Instrument title"
93
+ * state="error"
94
+ * errorMessage="Instrument missing in protocol"
95
+ * />
96
+ * ```
97
+ */
98
+ export declare const InstrumentCard: FC<Props>;
99
+ export {};
@@ -0,0 +1,99 @@
1
+ import { type FC } from "react";
2
+ /**
3
+ * The kind of instrument, which selects the leading icon. Overridden by
4
+ * `ExclamationMarkIcon` when `state` is `"error"`.
5
+ */
6
+ export type InstrumentType = "info" | "questionnaire" | "numeric" | "document" | "contact" | "other" | "scripted" | "sum";
7
+ type BaseProps = {
8
+ /** Selects the leading icon. */
9
+ type: InstrumentType;
10
+ /**
11
+ * Name of the instrument. Truncates with an ellipsis in the `detailed`
12
+ * variant; in `compact` it is the pill label, and is replaced by
13
+ * `errorMessage` when `state` is `"error"`.
14
+ */
15
+ title: string;
16
+ /**
17
+ * First cell of the meta row, e.g. `"Lesson"`. `detailed` only, and not
18
+ * rendered when `state` is `"error"` — the error message takes its place.
19
+ */
20
+ category?: string;
21
+ /**
22
+ * Second cell of the meta row, e.g. `"Comments ON"`, separated from
23
+ * `category` by a vertical rule. Rendered only alongside `category`.
24
+ * `detailed` only, and replaced by the error message in the error state.
25
+ */
26
+ meta?: string;
27
+ /**
28
+ * Instrument identifier, e.g. `"Id-30ry3-7240"`. Rendered as a bordered
29
+ * tag beneath the meta row. `detailed` only; omitted when absent.
30
+ */
31
+ id?: string;
32
+ /**
33
+ * Number shown in the trailing tag — how many times the instrument is used.
34
+ * `detailed` only; omitted when absent. `0` renders, it is not treated as
35
+ * empty.
36
+ */
37
+ count?: number;
38
+ /**
39
+ * `"compact"` is an inline pill of icon plus label, for listing
40
+ * instruments inside an action card. `"detailed"` is a full-width row with
41
+ * a title, meta row and tags.
42
+ *
43
+ * @default "compact"
44
+ */
45
+ variant?: "compact" | "detailed";
46
+ /** Merged onto the root element. */
47
+ className?: string;
48
+ };
49
+ /**
50
+ * `errorMessage` is what the error state renders — it replaces the label in
51
+ * the compact variant and the meta row in the detailed variant. Requiring it
52
+ * alongside `state="error"` makes the empty-error-label state impossible to
53
+ * express, rather than guarding against it at runtime.
54
+ *
55
+ * In the error state the icon becomes `ExclamationMarkIcon` and the icon,
56
+ * title and message all take the error colour.
57
+ *
58
+ * @default state "default"
59
+ */
60
+ type StateProps = {
61
+ state?: "default";
62
+ errorMessage?: never;
63
+ } | {
64
+ state: "error";
65
+ errorMessage: string;
66
+ };
67
+ export type Props = BaseProps & StateProps;
68
+ /**
69
+ * Renders a single instrument belonging to an action.
70
+ *
71
+ * Use `variant="compact"` for the inline pills listed on an `ActionCard`, and
72
+ * `variant="detailed"` for the full rows in `ActionCardDetailed`. Both of
73
+ * those consumers force the variant, so it is not part of the props they
74
+ * accept.
75
+ *
76
+ * @example
77
+ * ```tsx
78
+ * <InstrumentCard type="info" title="How to stop smoking" />
79
+ *
80
+ * <InstrumentCard
81
+ * variant="detailed"
82
+ * type="questionnaire"
83
+ * title="Daily health questionnaire"
84
+ * category="Questionnaire"
85
+ * meta="Comments ON"
86
+ * id="Id-30ry3-7240"
87
+ * count={4}
88
+ * />
89
+ *
90
+ * <InstrumentCard
91
+ * type="other"
92
+ * title="Instrument title"
93
+ * state="error"
94
+ * errorMessage="Instrument missing in protocol"
95
+ * />
96
+ * ```
97
+ */
98
+ export declare const InstrumentCard: FC<Props>;
99
+ export {};
@@ -94,6 +94,7 @@ export { Breadcrumbs, type BreadcrumbProps } from "./components/Breadcrumbs";
94
94
  export { PageHeader, type PageHeaderProps } from "./components/PageHeader";
95
95
  export { Tag } from "./components/Tag/Tag";
96
96
  export { TagGroup } from "./components/Tag/TagGroup";
97
+ export { InstrumentCard, type InstrumentType, type Props as InstrumentCardProps, } from "./components/InstrumentCard/InstrumentCard";
97
98
  export { Textarea, type TextareaProps, type ResizeTypes, } from "./components/Textarea/Textarea";
98
99
  export { TextEditor, type TextEditorTag, } from "./components/TextEditor/TextEditor";
99
100
  export { type TextEditorTranslations } from "./components/TextEditor/textEditorTranslations";
@@ -94,6 +94,7 @@ export { Breadcrumbs, type BreadcrumbProps } from "./components/Breadcrumbs";
94
94
  export { PageHeader, type PageHeaderProps } from "./components/PageHeader";
95
95
  export { Tag } from "./components/Tag/Tag";
96
96
  export { TagGroup } from "./components/Tag/TagGroup";
97
+ export { InstrumentCard, type InstrumentType, type Props as InstrumentCardProps, } from "./components/InstrumentCard/InstrumentCard";
97
98
  export { Textarea, type TextareaProps, type ResizeTypes, } from "./components/Textarea/Textarea";
98
99
  export { TextEditor, type TextEditorTag, } from "./components/TextEditor/TextEditor";
99
100
  export { type TextEditorTranslations } from "./components/TextEditor/textEditorTranslations";
@@ -0,0 +1,43 @@
1
+ import { type StoryObj } from "@storybook/react-vite";
2
+ import { type InstrumentType } from "../src/components/InstrumentCard/InstrumentCard";
3
+ declare const meta: {
4
+ title: string;
5
+ component: import("react").FC<import("../src").InstrumentCardProps>;
6
+ parameters: {
7
+ backgrounds: {
8
+ default: string;
9
+ };
10
+ };
11
+ argTypes: {
12
+ type: {
13
+ options: InstrumentType[];
14
+ control: {
15
+ type: "select";
16
+ };
17
+ };
18
+ variant: {
19
+ options: string[];
20
+ control: {
21
+ type: "select";
22
+ };
23
+ };
24
+ state: {
25
+ options: string[];
26
+ control: {
27
+ type: "select";
28
+ };
29
+ };
30
+ count: {
31
+ control: {
32
+ type: "number";
33
+ };
34
+ };
35
+ };
36
+ };
37
+ export default meta;
38
+ type Story = StoryObj<typeof meta>;
39
+ export declare const Base: Story;
40
+ export declare const EveryTypeCompact: Story;
41
+ export declare const EveryTypeDetailed: Story;
42
+ export declare const DetailedOptionalFields: Story;
43
+ export declare const ErrorStates: Story;
@@ -1624,6 +1624,9 @@ button, input:where([type='button'], [type='reset'], [type='submit']), ::file-se
1624
1624
  .ui\:h-\[11px\] {
1625
1625
  height: 11px;
1626
1626
  }
1627
+ .ui\:h-\[12px\] {
1628
+ height: 12px;
1629
+ }
1627
1630
  .ui\:h-\[20px\] {
1628
1631
  height: 20px;
1629
1632
  }
@@ -1966,6 +1969,9 @@ button, input:where([type='button'], [type='reset'], [type='submit']), ::file-se
1966
1969
  .ui\:max-w-\[500px\] {
1967
1970
  max-width: 500px;
1968
1971
  }
1972
+ .ui\:max-w-\[560px\] {
1973
+ max-width: 560px;
1974
+ }
1969
1975
  .ui\:max-w-\[900px\] {
1970
1976
  max-width: 900px;
1971
1977
  }
@@ -1978,6 +1984,9 @@ button, input:where([type='button'], [type='reset'], [type='submit']), ::file-se
1978
1984
  .ui\:max-w-screen {
1979
1985
  max-width: 100vw;
1980
1986
  }
1987
+ .ui\:min-w-0 {
1988
+ min-width: calc(var(--ui-spacing) * 0);
1989
+ }
1981
1990
  .ui\:min-w-24 {
1982
1991
  min-width: 1.5rem;
1983
1992
  }
@@ -2922,6 +2931,9 @@ button, input:where([type='button'], [type='reset'], [type='submit']), ::file-se
2922
2931
  .ui\:bg-blue-400 {
2923
2932
  background-color: var(--ui-color-blue-400);
2924
2933
  }
2934
+ .ui\:bg-border-neutral-primary-default {
2935
+ background-color: var(--ui-primitive-color-grey-300);
2936
+ }
2925
2937
  .ui\:bg-color-divider {
2926
2938
  background-color: #eeeeee;
2927
2939
  }
@@ -3848,6 +3860,12 @@ button, input:where([type='button'], [type='reset'], [type='submit']), ::file-se
3848
3860
  .ui\:text-green-800 {
3849
3861
  color: var(--ui-color-green-800);
3850
3862
  }
3863
+ .ui\:text-icon-brand-primary-default {
3864
+ color: var(--ui-primitive-color-brand-700);
3865
+ }
3866
+ .ui\:text-icon-error-primary-default {
3867
+ color: var(--ui-primitive-color-red-900);
3868
+ }
3851
3869
  .ui\:text-negative-solid {
3852
3870
  color: var(--ui-color-red-400);
3853
3871
  }