@dilipod/ui 0.4.33 → 0.4.35

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.
@@ -53,12 +53,14 @@ const sheetVariants = cva(
53
53
 
54
54
  interface SheetContentProps
55
55
  extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
56
- VariantProps<typeof sheetVariants> {}
56
+ VariantProps<typeof sheetVariants> {
57
+ hideClose?: boolean
58
+ }
57
59
 
58
60
  const SheetContent = React.forwardRef<
59
61
  React.ElementRef<typeof SheetPrimitive.Content>,
60
62
  SheetContentProps
61
- >(({ side = 'right', className, children, ...props }, ref) => (
63
+ >(({ side = 'right', className, children, hideClose, ...props }, ref) => (
62
64
  <SheetPortal>
63
65
  <SheetOverlay />
64
66
  <SheetPrimitive.Content
@@ -67,11 +69,13 @@ const SheetContent = React.forwardRef<
67
69
  {...props}
68
70
  >
69
71
  {children}
70
- {/* @ts-expect-error - Radix Dialog Close accepts className and children at runtime */}
71
- <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-gray-100">
72
- <X className="h-4 w-4" />
73
- <span className="sr-only">Close</span>
74
- </SheetPrimitive.Close>
72
+ {!hideClose && (
73
+ // @ts-expect-error - Radix Dialog Close accepts className and children at runtime
74
+ <SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none data-[state=open]:bg-gray-100">
75
+ <X className="h-4 w-4" />
76
+ <span className="sr-only">Close</span>
77
+ </SheetPrimitive.Close>
78
+ )}
75
79
  </SheetPrimitive.Content>
76
80
  </SheetPortal>
77
81
  ))
package/src/lib/slack.ts CHANGED
@@ -98,6 +98,157 @@ export function slackActions(
98
98
  }
99
99
  }
100
100
 
101
+ // ============================================
102
+ // Modal & Select Builders
103
+ // ============================================
104
+
105
+ export interface SlackModalView {
106
+ type: 'modal'
107
+ callback_id: string
108
+ title: { type: 'plain_text'; text: string }
109
+ submit?: { type: 'plain_text'; text: string }
110
+ close?: { type: 'plain_text'; text: string }
111
+ blocks: SlackBlock[]
112
+ private_metadata?: string
113
+ }
114
+
115
+ export interface SlackOptionGroup {
116
+ label: { type: 'plain_text'; text: string }
117
+ options: Array<{
118
+ text: { type: 'plain_text'; text: string }
119
+ value: string
120
+ }>
121
+ }
122
+
123
+ /**
124
+ * Build a modal view for Slack.
125
+ *
126
+ * slackModal({
127
+ * callbackId: 'run_process',
128
+ * title: 'Run a Process',
129
+ * submitText: 'Run',
130
+ * blocks: [...],
131
+ * })
132
+ */
133
+ export function slackModal(options: {
134
+ callbackId: string
135
+ title: string
136
+ submitText?: string
137
+ closeText?: string
138
+ blocks: SlackBlock[]
139
+ privateMetadata?: string
140
+ }): SlackModalView {
141
+ return {
142
+ type: 'modal',
143
+ callback_id: options.callbackId,
144
+ title: { type: 'plain_text', text: options.title },
145
+ ...(options.submitText
146
+ ? { submit: { type: 'plain_text', text: options.submitText } }
147
+ : {}),
148
+ ...(options.closeText
149
+ ? { close: { type: 'plain_text', text: options.closeText } }
150
+ : {}),
151
+ blocks: options.blocks,
152
+ ...(options.privateMetadata
153
+ ? { private_metadata: options.privateMetadata }
154
+ : {}),
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Build a static select input block (for modals or messages).
160
+ *
161
+ * slackStaticSelect({
162
+ * blockId: 'process_select',
163
+ * actionId: 'process_id',
164
+ * label: 'Process',
165
+ * placeholder: 'Select a process',
166
+ * optionGroups: [
167
+ * { label: 'Invoice Bot', options: [{ text: 'Send Invoices', value: 'uuid' }] },
168
+ * ],
169
+ * })
170
+ */
171
+ export function slackStaticSelect(options: {
172
+ blockId: string
173
+ actionId: string
174
+ label: string
175
+ placeholder?: string
176
+ options?: Array<{ text: string; value: string }>
177
+ optionGroups?: Array<{ label: string; options: Array<{ text: string; value: string }> }>
178
+ }): SlackBlock {
179
+ const element: Record<string, unknown> = {
180
+ type: 'static_select',
181
+ action_id: options.actionId,
182
+ placeholder: { type: 'plain_text', text: options.placeholder || 'Select...' },
183
+ }
184
+
185
+ if (options.optionGroups) {
186
+ element.option_groups = options.optionGroups.map((group) => ({
187
+ label: { type: 'plain_text', text: group.label },
188
+ options: group.options.map((opt) => ({
189
+ text: { type: 'plain_text', text: opt.text },
190
+ value: opt.value,
191
+ })),
192
+ }))
193
+ } else if (options.options) {
194
+ element.options = options.options.map((opt) => ({
195
+ text: { type: 'plain_text', text: opt.text },
196
+ value: opt.value,
197
+ }))
198
+ }
199
+
200
+ return {
201
+ type: 'input',
202
+ block_id: options.blockId,
203
+ label: { type: 'plain_text', text: options.label },
204
+ element,
205
+ } as unknown as SlackBlock
206
+ }
207
+
208
+ /**
209
+ * Build a plain text input block (for modals).
210
+ */
211
+ export function slackTextInput(options: {
212
+ blockId: string
213
+ actionId: string
214
+ label: string
215
+ placeholder?: string
216
+ optional?: boolean
217
+ multiline?: boolean
218
+ }): SlackBlock {
219
+ return {
220
+ type: 'input',
221
+ block_id: options.blockId,
222
+ optional: options.optional ?? false,
223
+ label: { type: 'plain_text', text: options.label },
224
+ element: {
225
+ type: 'plain_text_input',
226
+ action_id: options.actionId,
227
+ ...(options.placeholder
228
+ ? { placeholder: { type: 'plain_text', text: options.placeholder } }
229
+ : {}),
230
+ ...(options.multiline ? { multiline: true } : {}),
231
+ },
232
+ } as unknown as SlackBlock
233
+ }
234
+
235
+ /**
236
+ * Build a divider block.
237
+ */
238
+ export function slackDivider(): SlackBlock {
239
+ return { type: 'divider' } as SlackBlock
240
+ }
241
+
242
+ /**
243
+ * Build a context block (small muted text).
244
+ */
245
+ export function slackContext(text: string): SlackBlock {
246
+ return {
247
+ type: 'context',
248
+ elements: [{ type: 'mrkdwn', text }],
249
+ } as unknown as SlackBlock
250
+ }
251
+
101
252
  // ============================================
102
253
  // Message Builder
103
254
  // ============================================
package/src/server.ts CHANGED
@@ -10,8 +10,25 @@
10
10
  export { emailTemplate, buttonHtml, infoBoxHtml, noteBoxHtml } from './lib/email'
11
11
 
12
12
  // Slack Block Kit Helpers
13
- export { slackMessage, slackSection, slackFields, slackActions } from './lib/slack'
14
- export type { SlackBlock, SlackElement, SlackField, SlackMessage } from './lib/slack'
13
+ export {
14
+ slackMessage,
15
+ slackSection,
16
+ slackFields,
17
+ slackActions,
18
+ slackModal,
19
+ slackStaticSelect,
20
+ slackTextInput,
21
+ slackDivider,
22
+ slackContext,
23
+ } from './lib/slack'
24
+ export type {
25
+ SlackBlock,
26
+ SlackElement,
27
+ SlackField,
28
+ SlackMessage,
29
+ SlackModalView,
30
+ SlackOptionGroup,
31
+ } from './lib/slack'
15
32
 
16
33
  // Formatting Utilities
17
34
  export { formatCentsToEuros, formatEuros, formatDuration, formatRelativeTime } from './lib/formatting'