@agility/plenum-ui 2.3.2 → 2.3.4
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/index.d.ts +12 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/tailwind.css +22 -0
- package/dist/types/stories/atoms/Typography/Paragraph/Paragraph.d.ts +2 -2
- package/dist/types/stories/molecules/inputs/select/Select.d.ts +10 -1
- package/package.json +1 -1
- package/stories/atoms/Typography/Paragraph/Paragraph.tsx +3 -3
- package/stories/molecules/inputs/select/Select.stories.tsx +27 -2
- package/stories/molecules/inputs/select/Select.tsx +73 -10
package/dist/tailwind.css
CHANGED
|
@@ -2037,10 +2037,18 @@ select {
|
|
|
2037
2037
|
width: 100%;
|
|
2038
2038
|
}
|
|
2039
2039
|
|
|
2040
|
+
.min-w-0 {
|
|
2041
|
+
min-width: 0px;
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2040
2044
|
.min-w-\[320px\] {
|
|
2041
2045
|
min-width: 320px;
|
|
2042
2046
|
}
|
|
2043
2047
|
|
|
2048
|
+
.flex-1 {
|
|
2049
|
+
flex: 1 1 0%;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2044
2052
|
.shrink-0 {
|
|
2045
2053
|
flex-shrink: 0;
|
|
2046
2054
|
}
|
|
@@ -71735,6 +71743,11 @@ select {
|
|
|
71735
71743
|
color: rgb(107 114 128 / var(--tw-text-opacity, 1));
|
|
71736
71744
|
}
|
|
71737
71745
|
|
|
71746
|
+
.text-neutral-700 {
|
|
71747
|
+
--tw-text-opacity: 1;
|
|
71748
|
+
color: rgb(55 65 81 / var(--tw-text-opacity, 1));
|
|
71749
|
+
}
|
|
71750
|
+
|
|
71738
71751
|
.text-orange-100 {
|
|
71739
71752
|
--tw-text-opacity: 1;
|
|
71740
71753
|
color: rgb(255 237 213 / var(--tw-text-opacity, 1));
|
|
@@ -73515,6 +73528,11 @@ select {
|
|
|
73515
73528
|
color: rgb(131 24 67 / 0.95);
|
|
73516
73529
|
}
|
|
73517
73530
|
|
|
73531
|
+
.text-primary-700 {
|
|
73532
|
+
--tw-text-opacity: 1;
|
|
73533
|
+
color: rgb(109 40 217 / var(--tw-text-opacity, 1));
|
|
73534
|
+
}
|
|
73535
|
+
|
|
73518
73536
|
.text-purple-100 {
|
|
73519
73537
|
--tw-text-opacity: 1;
|
|
73520
73538
|
color: rgb(222 204 246 / var(--tw-text-opacity, 1));
|
|
@@ -79020,6 +79038,10 @@ select {
|
|
|
79020
79038
|
--anchor-gap: 8px;
|
|
79021
79039
|
}
|
|
79022
79040
|
|
|
79041
|
+
.\!\[max-width\:var\(--dropdown-max-width\)\] {
|
|
79042
|
+
max-width: var(--dropdown-max-width) !important;
|
|
79043
|
+
}
|
|
79044
|
+
|
|
79023
79045
|
.placeholder\:text-gray-400::-moz-placeholder {
|
|
79024
79046
|
--tw-text-opacity: 1;
|
|
79025
79047
|
color: rgb(156 163 175 / var(--tw-text-opacity, 1));
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
type ParagraphAs = "span" | "p" | "label" | "strong" | "em";
|
|
2
2
|
type ParagraphSize = "xl" | "lg" | "md" | "sm" | "xs";
|
|
3
|
-
export interface ParagraphProps {
|
|
3
|
+
export interface ParagraphProps extends React.HTMLAttributes<HTMLElement> {
|
|
4
4
|
as?: ParagraphAs;
|
|
5
5
|
size?: ParagraphSize;
|
|
6
6
|
children: React.ReactNode;
|
|
7
7
|
className?: string;
|
|
8
8
|
}
|
|
9
|
-
export default function Paragraph({ as, size, children, className }: ParagraphProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default function Paragraph({ as, size, children, className, ...rest }: ParagraphProps): import("react/jsx-runtime").JSX.Element;
|
|
10
10
|
export {};
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import { UnifiedIconName } from "@/stories/atoms/icons/DynamicIcon";
|
|
2
3
|
export interface ISimpleSelectOptions {
|
|
3
4
|
label: string;
|
|
4
5
|
value: string;
|
|
5
|
-
|
|
6
|
+
icon?: UnifiedIconName;
|
|
6
7
|
description?: string;
|
|
8
|
+
caption?: string;
|
|
9
|
+
}
|
|
10
|
+
interface LabelAction {
|
|
11
|
+
label: string;
|
|
12
|
+
onClick: () => void;
|
|
13
|
+
className?: string;
|
|
7
14
|
}
|
|
8
15
|
export interface ISelectProps {
|
|
9
16
|
/** Label */
|
|
@@ -30,6 +37,8 @@ export interface ISelectProps {
|
|
|
30
37
|
inputRef?: React.RefObject<HTMLInputElement>;
|
|
31
38
|
placeholder?: string;
|
|
32
39
|
dropdownMaxHeight?: number;
|
|
40
|
+
dropdownMaxWidth?: number;
|
|
41
|
+
labelAction?: LabelAction;
|
|
33
42
|
}
|
|
34
43
|
declare const Select: React.FC<ISelectProps>;
|
|
35
44
|
export default Select;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { default as cn } from "classnames";
|
|
|
3
3
|
type ParagraphAs = "span" | "p" | "label" | "strong" | "em";
|
|
4
4
|
type ParagraphSize = "xl" | "lg" | "md" | "sm" | "xs";
|
|
5
5
|
|
|
6
|
-
export interface ParagraphProps {
|
|
6
|
+
export interface ParagraphProps extends React.HTMLAttributes<HTMLElement> {
|
|
7
7
|
as?: ParagraphAs;
|
|
8
8
|
size?: ParagraphSize;
|
|
9
9
|
children: React.ReactNode;
|
|
@@ -18,8 +18,8 @@ const paragraphStyles: Record<ParagraphSize, string> = {
|
|
|
18
18
|
xs: "text-[10px] leading-[12px]"
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
export default function Paragraph({ as = "p", size = "md", children, className }: ParagraphProps) {
|
|
21
|
+
export default function Paragraph({ as = "p", size = "md", children, className, ...rest }: ParagraphProps) {
|
|
22
22
|
const Tag = as;
|
|
23
23
|
|
|
24
|
-
return <Tag className={cn("gray-900 font-normal", paragraphStyles[size], className)}>{children}</Tag>;
|
|
24
|
+
return <Tag className={cn("gray-900 font-normal", paragraphStyles[size], className)} {...rest}>{children}</Tag>;
|
|
25
25
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { action } from "@storybook/addon-actions";
|
|
2
3
|
import Select from "./Select";
|
|
3
4
|
|
|
4
5
|
const meta: Meta<typeof Select> = {
|
|
@@ -61,8 +62,14 @@ export const DefaultSelect: TStory = {
|
|
|
61
62
|
id: "select",
|
|
62
63
|
name: "select",
|
|
63
64
|
options: [
|
|
64
|
-
{
|
|
65
|
-
|
|
65
|
+
{
|
|
66
|
+
label: "All",
|
|
67
|
+
value: ""
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
label: "Canadian French blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah",
|
|
71
|
+
value: "fr-ca"
|
|
72
|
+
}
|
|
66
73
|
],
|
|
67
74
|
isDisabled: false,
|
|
68
75
|
isError: false,
|
|
@@ -84,6 +91,24 @@ export const ManyOptions: TStory = {
|
|
|
84
91
|
}
|
|
85
92
|
};
|
|
86
93
|
|
|
94
|
+
export const WithLabelAction: TStory = {
|
|
95
|
+
args: {
|
|
96
|
+
label: "Batch",
|
|
97
|
+
id: "select-label-action",
|
|
98
|
+
name: "select-label-action",
|
|
99
|
+
isRequired: true,
|
|
100
|
+
options: [
|
|
101
|
+
{ label: "Batch 1", value: "batch-1" },
|
|
102
|
+
{ label: "Batch 2", value: "batch-2" },
|
|
103
|
+
{ label: "Batch 3", value: "batch-3" }
|
|
104
|
+
],
|
|
105
|
+
labelAction: {
|
|
106
|
+
label: "Add new batch",
|
|
107
|
+
onClick: action("labelAction clicked")
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
87
112
|
export const DefaultSelectDarkBG: TStory = {
|
|
88
113
|
args: {
|
|
89
114
|
label: "Label",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
2
2
|
import InputLabel from "@/stories/molecules/inputs/InputLabel";
|
|
3
|
-
import { DynamicIcon } from "@/stories/atoms/icons/DynamicIcon";
|
|
3
|
+
import { DynamicIcon, UnifiedIconName } from "@/stories/atoms/icons/DynamicIcon";
|
|
4
4
|
import { useId } from "@/utils/useId";
|
|
5
5
|
import { default as cn } from "classnames";
|
|
6
6
|
import {
|
|
@@ -11,12 +11,20 @@ import {
|
|
|
11
11
|
ComboboxOption
|
|
12
12
|
} from "@headlessui/react";
|
|
13
13
|
import { Paragraph } from "@/stories/atoms/Typography/Paragraph";
|
|
14
|
+
import { Label } from "@/stories/atoms/Typography/Label";
|
|
14
15
|
|
|
15
16
|
export interface ISimpleSelectOptions {
|
|
16
17
|
label: string;
|
|
17
18
|
value: string;
|
|
18
|
-
|
|
19
|
+
icon?: UnifiedIconName;
|
|
19
20
|
description?: string;
|
|
21
|
+
caption?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface LabelAction {
|
|
25
|
+
label: string;
|
|
26
|
+
onClick: () => void;
|
|
27
|
+
className?: string;
|
|
20
28
|
}
|
|
21
29
|
|
|
22
30
|
export interface ISelectProps {
|
|
@@ -44,6 +52,8 @@ export interface ISelectProps {
|
|
|
44
52
|
inputRef?: React.RefObject<HTMLInputElement>;
|
|
45
53
|
placeholder?: string;
|
|
46
54
|
dropdownMaxHeight?: number;
|
|
55
|
+
dropdownMaxWidth?: number;
|
|
56
|
+
labelAction?: LabelAction;
|
|
47
57
|
}
|
|
48
58
|
|
|
49
59
|
const Select: React.FC<ISelectProps> = ({
|
|
@@ -62,7 +72,9 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
62
72
|
message,
|
|
63
73
|
inputRef,
|
|
64
74
|
placeholder = "Select",
|
|
65
|
-
dropdownMaxHeight = 240
|
|
75
|
+
dropdownMaxHeight = 240,
|
|
76
|
+
dropdownMaxWidth = 240,
|
|
77
|
+
labelAction
|
|
66
78
|
}) => {
|
|
67
79
|
const uniqueID = useId();
|
|
68
80
|
if (!id) id = `select-${uniqueID}`;
|
|
@@ -98,7 +110,25 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
98
110
|
|
|
99
111
|
return (
|
|
100
112
|
<div className={wrapperStyle}>
|
|
101
|
-
{label
|
|
113
|
+
{(label || labelAction) && (
|
|
114
|
+
<div className="flex items-center justify-between">
|
|
115
|
+
{label && (
|
|
116
|
+
<InputLabel
|
|
117
|
+
id={`${id}-label`}
|
|
118
|
+
label={label}
|
|
119
|
+
isRequired={isRequired}
|
|
120
|
+
noMarginBottom={!!labelAction}
|
|
121
|
+
/>
|
|
122
|
+
)}
|
|
123
|
+
{labelAction && (
|
|
124
|
+
<button type="button" onClick={labelAction.onClick}>
|
|
125
|
+
<Label size="sm" className={cn("text-primary-700", labelAction.className)}>
|
|
126
|
+
{labelAction.label}
|
|
127
|
+
</Label>
|
|
128
|
+
</button>
|
|
129
|
+
)}
|
|
130
|
+
</div>
|
|
131
|
+
)}
|
|
102
132
|
|
|
103
133
|
<HeadlessCombobox value={selectedOption} onChange={handleChange} disabled={isDisabled} immediate by="value">
|
|
104
134
|
<div ref={containerRef} className="relative w-full">
|
|
@@ -142,13 +172,15 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
142
172
|
style={
|
|
143
173
|
{
|
|
144
174
|
"--anchor-max-height": `${dropdownMaxHeight}px`,
|
|
145
|
-
|
|
175
|
+
"--dropdown-max-width": `${dropdownMaxWidth}px`,
|
|
176
|
+
minWidth: Math.max(containerWidth ?? 0, 60)
|
|
146
177
|
} as React.CSSProperties
|
|
147
178
|
}
|
|
148
179
|
className={cn(
|
|
149
180
|
"z-[9999] overflow-auto rounded bg-white py-1",
|
|
150
181
|
"text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none",
|
|
151
|
-
"[--anchor-gap:8px]"
|
|
182
|
+
"[--anchor-gap:8px]",
|
|
183
|
+
"![max-width:var(--dropdown-max-width)]"
|
|
152
184
|
)}
|
|
153
185
|
>
|
|
154
186
|
{options.map((option) => (
|
|
@@ -163,10 +195,41 @@ const Select: React.FC<ISelectProps> = ({
|
|
|
163
195
|
}
|
|
164
196
|
>
|
|
165
197
|
{({ selected }) => (
|
|
166
|
-
<div className="py-xxsm px-sm
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
198
|
+
<div className="flex justify-between items-center py-xxsm px-sm gap-4">
|
|
199
|
+
<div className="flex flex-col flex-1 min-w-0">
|
|
200
|
+
<div className="flex items-center gap-xsm">
|
|
201
|
+
<Paragraph
|
|
202
|
+
size="md"
|
|
203
|
+
className="text-neutral-700 truncate min-w-0"
|
|
204
|
+
title={option.label}
|
|
205
|
+
onMouseEnter={(e) => {
|
|
206
|
+
const el = e.currentTarget;
|
|
207
|
+
if (el.scrollWidth <= el.clientWidth)
|
|
208
|
+
el.removeAttribute("title");
|
|
209
|
+
}}
|
|
210
|
+
onMouseLeave={(e) => {
|
|
211
|
+
e.currentTarget.setAttribute("title", option.label);
|
|
212
|
+
}}
|
|
213
|
+
>
|
|
214
|
+
{option.label}
|
|
215
|
+
</Paragraph>
|
|
216
|
+
{option.description ? (
|
|
217
|
+
<Paragraph size="md" className="text-neutral-500">
|
|
218
|
+
{option.description}
|
|
219
|
+
</Paragraph>
|
|
220
|
+
) : null}
|
|
221
|
+
</div>
|
|
222
|
+
{option.caption ? (
|
|
223
|
+
<Paragraph size="sm" className="text-neutral-500">
|
|
224
|
+
{option.caption}
|
|
225
|
+
</Paragraph>
|
|
226
|
+
) : null}
|
|
227
|
+
</div>
|
|
228
|
+
{option.icon ? (
|
|
229
|
+
<DynamicIcon
|
|
230
|
+
icon={option.icon}
|
|
231
|
+
className="shrink-0 w-5 h-5 text-neutral-500"
|
|
232
|
+
/>
|
|
170
233
|
) : null}
|
|
171
234
|
</div>
|
|
172
235
|
)}
|