@sikka/hawa 0.0.229 → 0.0.231
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/styles.css +65 -1
- package/es/elements/ArrowCarousel.d.ts +13 -0
- package/es/elements/FloatingComment - ContentEditable.d.ts +6 -0
- package/es/elements/FloatingComment.d.ts +6 -0
- package/es/elements/index.d.ts +2 -0
- package/es/index.es.js +1 -1
- package/lib/elements/ArrowCarousel.d.ts +13 -0
- package/lib/elements/FloatingComment - ContentEditable.d.ts +6 -0
- package/lib/elements/FloatingComment.d.ts +6 -0
- package/lib/elements/index.d.ts +2 -0
- package/lib/index.js +1 -1
- package/package.json +3 -2
- package/src/elements/ArrowCarousel.tsx +86 -0
- package/src/elements/FloatingComment - ContentEditable.tsx +514 -0
- package/src/elements/FloatingComment.tsx +369 -0
- package/src/elements/index.ts +2 -0
- package/src/styles.css +65 -1
- package/src/tailwind.css +1 -1
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import React, { useRef, useState, useEffect } from "react"
|
|
2
|
+
import { RichTextarea } from "rich-textarea"
|
|
3
|
+
import clsx from "clsx"
|
|
4
|
+
|
|
5
|
+
const Property = (props) => {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
className="border-box mr-[5px] flex h-[32px] w-[32px] items-center justify-center rounded bg-gray-400 p-2"
|
|
9
|
+
onClick={props.onClick}
|
|
10
|
+
>
|
|
11
|
+
{props.name}
|
|
12
|
+
</div>
|
|
13
|
+
)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type ComponentTypes = {
|
|
17
|
+
foo?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// TODO: Handle copy pasting by assigning to local storage ?
|
|
21
|
+
|
|
22
|
+
const styleClasses = {
|
|
23
|
+
bold: "font-bold",
|
|
24
|
+
italic: "italic",
|
|
25
|
+
under: "underline",
|
|
26
|
+
strike: "line-through",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const FloatingComment: React.FunctionComponent<ComponentTypes> = (
|
|
30
|
+
props
|
|
31
|
+
) => {
|
|
32
|
+
const [text, setText] = useState({
|
|
33
|
+
content: "",
|
|
34
|
+
stylings: [], // A styling is an object with 2 indices specifying a substring of text, and the applied effect
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const field = useRef(null)
|
|
38
|
+
|
|
39
|
+
// utility functions
|
|
40
|
+
const getRange = (start, end) => {
|
|
41
|
+
let result = []
|
|
42
|
+
for (let i = start; i <= end; i++) {
|
|
43
|
+
result.push(i)
|
|
44
|
+
}
|
|
45
|
+
return result
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const intersection = (setA, setB) => {
|
|
49
|
+
const _intersection = new Set()
|
|
50
|
+
for (const elem of setB) {
|
|
51
|
+
if (setA.has(elem)) {
|
|
52
|
+
_intersection.add(elem)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return _intersection
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const getMinimum = (array) => {
|
|
59
|
+
return array.sort((a, b) => a - b)[0]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const getMaximum = (array) => {
|
|
63
|
+
return array.sort((a, b) => b - a)[0]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// -1 - types dont match
|
|
67
|
+
// 0 - s1 is surrounded or on the edge of the s2
|
|
68
|
+
// 1 - s1 intersects with s2
|
|
69
|
+
// 2 - s1 does not intersect with s2
|
|
70
|
+
const getCorrelation = (styling1, styling2) => {
|
|
71
|
+
if (styling1.type != styling2.type) return -1
|
|
72
|
+
|
|
73
|
+
if (
|
|
74
|
+
styling2.start <= styling1.start &&
|
|
75
|
+
styling2.finish >= styling1.finish
|
|
76
|
+
) {
|
|
77
|
+
return 0
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let indices1 = new Set(getRange(styling1.start - 1, styling1.finish - 1))
|
|
81
|
+
let indices2 = new Set(getRange(styling2.start - 1, styling2.finish - 1))
|
|
82
|
+
|
|
83
|
+
let result = intersection(indices1, indices2)
|
|
84
|
+
|
|
85
|
+
return result.size == 0 ? 2 : 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Correlation handler
|
|
89
|
+
const stylingSplice = (correlations, stylings, current, type) => {
|
|
90
|
+
// Only one surround correlation is possible at one time, so use .find to fetch it
|
|
91
|
+
|
|
92
|
+
let [_, index, styling] = correlations.find(([c, _, __]) => c == 0)
|
|
93
|
+
|
|
94
|
+
// Remove correlated styling
|
|
95
|
+
stylings = stylings.filter((_, _index) => _index != index)
|
|
96
|
+
|
|
97
|
+
// Get splices
|
|
98
|
+
let added = [
|
|
99
|
+
{
|
|
100
|
+
type: type,
|
|
101
|
+
start: getMinimum([styling.start, current.start]),
|
|
102
|
+
finish: getMaximum([styling.start, current.start]),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: type,
|
|
106
|
+
start: getMinimum([styling.finish, current.finish]),
|
|
107
|
+
finish: getMaximum([styling.finish, current.finish]),
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
// Remove empty splices (edge cases)
|
|
112
|
+
added = added.filter((item) => item.start != item.finish)
|
|
113
|
+
|
|
114
|
+
// Add to current stylings
|
|
115
|
+
stylings = [...stylings, ...added]
|
|
116
|
+
|
|
117
|
+
return stylings
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Correlation handler
|
|
121
|
+
const stylingIntersect = (correlations, stylings, current, type) => {
|
|
122
|
+
// Filter out all intersected stylings
|
|
123
|
+
let intersections = correlations
|
|
124
|
+
.filter(([c, _, __]) => c == 1)
|
|
125
|
+
.map(([_, index, styling]) => {
|
|
126
|
+
return [index, styling]
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Add current styling with no index for the sake for endpoint indices
|
|
130
|
+
intersections.push([-1, current])
|
|
131
|
+
|
|
132
|
+
// Get minimum intersection start index
|
|
133
|
+
let start = intersections
|
|
134
|
+
.map(([_, styling]) => styling.start)
|
|
135
|
+
.sort((a, b) => a - b)[0]
|
|
136
|
+
|
|
137
|
+
// Get maximum intersection start index
|
|
138
|
+
let finish = intersections
|
|
139
|
+
.map(([_, styling]) => styling.finish)
|
|
140
|
+
.sort((a, b) => b - a)[0]
|
|
141
|
+
|
|
142
|
+
// Get indices of all intersection
|
|
143
|
+
let indices = intersections.map((e) => e[0])
|
|
144
|
+
|
|
145
|
+
// Remove all from resulting styling array
|
|
146
|
+
stylings = stylings.filter((_, index) => !indices.includes(index))
|
|
147
|
+
|
|
148
|
+
// Add widest styling which encompasses all intersections
|
|
149
|
+
stylings.push({
|
|
150
|
+
type: type,
|
|
151
|
+
start: start,
|
|
152
|
+
finish: finish,
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
return stylings
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const perform = (id) => {
|
|
159
|
+
let stylings = text.stylings.slice()
|
|
160
|
+
var selectionStart = field.current.selectionStart
|
|
161
|
+
var selectionEnd = field.current.selectionEnd
|
|
162
|
+
|
|
163
|
+
if (selectionStart == selectionEnd) return
|
|
164
|
+
|
|
165
|
+
let current = {
|
|
166
|
+
type: id,
|
|
167
|
+
start: selectionStart,
|
|
168
|
+
finish: selectionEnd,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let correlations = []
|
|
172
|
+
|
|
173
|
+
// Check the correlation between this requested styling and all other stylings
|
|
174
|
+
for (let i = 0; i < stylings.length; i++) {
|
|
175
|
+
let styling = stylings[i]
|
|
176
|
+
let correlation = getCorrelation(current, styling)
|
|
177
|
+
|
|
178
|
+
if (correlation != -1) correlations.push([correlation, i, styling])
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let result
|
|
182
|
+
|
|
183
|
+
if (correlations.find(([c, _, __]) => c == 1)) {
|
|
184
|
+
result = stylingIntersect(correlations, stylings, current, id)
|
|
185
|
+
} else if (correlations.find(([c, _, __]) => c == 0)) {
|
|
186
|
+
result = stylingSplice(correlations, stylings, current, id)
|
|
187
|
+
} else if (
|
|
188
|
+
correlations.find(([c, _, __]) => c == 2) ||
|
|
189
|
+
correlations.length == 0
|
|
190
|
+
) {
|
|
191
|
+
result = [...stylings, current]
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
setText({
|
|
195
|
+
...text,
|
|
196
|
+
stylings: result,
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Get stylings encompassing an index within it's range
|
|
201
|
+
const getIntersectStylings = (index, startOffset = 0, finishOffset = 0) => {
|
|
202
|
+
// Find all stylings with encompassing range
|
|
203
|
+
let matches = text.stylings.filter(
|
|
204
|
+
({ start, finish }) =>
|
|
205
|
+
index >= start + startOffset && index < finish + finishOffset
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return matches
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Get stylings after an index
|
|
212
|
+
const getSucceedStylings = (index) => {
|
|
213
|
+
// Find all stylings after the index
|
|
214
|
+
let matches = text.stylings.filter(({ start, finish }) => start >= index)
|
|
215
|
+
|
|
216
|
+
return matches
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const getStylingIndex = (styling) => {
|
|
220
|
+
return text.stylings.findIndex(
|
|
221
|
+
(item) =>
|
|
222
|
+
item.start == styling.start &&
|
|
223
|
+
item.finish == styling.finish &&
|
|
224
|
+
item.type == styling.type
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const onChange = (value) => {
|
|
229
|
+
let difference = value.length - text.content.length
|
|
230
|
+
|
|
231
|
+
let selection = field.current.selectionStart - difference
|
|
232
|
+
|
|
233
|
+
let stylings = text.stylings.slice()
|
|
234
|
+
let succeeding = getSucceedStylings(selection)
|
|
235
|
+
let changes = []
|
|
236
|
+
|
|
237
|
+
for (let succeed of succeeding) {
|
|
238
|
+
let index = getStylingIndex(succeed)
|
|
239
|
+
let styling = stylings[index]
|
|
240
|
+
|
|
241
|
+
changes.push([
|
|
242
|
+
index,
|
|
243
|
+
styling.start + difference,
|
|
244
|
+
styling.finish + difference,
|
|
245
|
+
])
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
let intersecting = getIntersectStylings(selection, 1, 1)
|
|
249
|
+
|
|
250
|
+
for (let intersect of intersecting) {
|
|
251
|
+
let index = getStylingIndex(intersect)
|
|
252
|
+
let styling = stylings[index]
|
|
253
|
+
|
|
254
|
+
changes.push([index, styling.start, styling.finish + difference])
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
let spliced = []
|
|
258
|
+
for (let [index, start, finish] of changes) {
|
|
259
|
+
stylings[index] = {
|
|
260
|
+
...stylings[index],
|
|
261
|
+
start: start,
|
|
262
|
+
finish: finish,
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (start >= finish) spliced.push(index)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
stylings = stylings.filter((_, index) => !spliced.includes(index))
|
|
269
|
+
|
|
270
|
+
setText({ ...text, content: value, stylings: stylings })
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return (
|
|
274
|
+
<div className="align-center box-border flex h-min w-[400px] flex-col items-center justify-center rounded bg-gray-300 shadow-md">
|
|
275
|
+
<div className={clsx("flex w-full flex-row justify-start p-2")}>
|
|
276
|
+
<Property
|
|
277
|
+
name="B"
|
|
278
|
+
onClick={() => {
|
|
279
|
+
perform("bold")
|
|
280
|
+
}}
|
|
281
|
+
/>
|
|
282
|
+
<Property
|
|
283
|
+
name="I"
|
|
284
|
+
onClick={() => {
|
|
285
|
+
perform("italic")
|
|
286
|
+
}}
|
|
287
|
+
/>
|
|
288
|
+
<Property
|
|
289
|
+
name="U"
|
|
290
|
+
onClick={() => {
|
|
291
|
+
perform("under")
|
|
292
|
+
}}
|
|
293
|
+
/>
|
|
294
|
+
<Property
|
|
295
|
+
name="S"
|
|
296
|
+
onClick={() => {
|
|
297
|
+
perform("strike")
|
|
298
|
+
}}
|
|
299
|
+
/>
|
|
300
|
+
</div>
|
|
301
|
+
<div className="h-[1px] w-full bg-slate-600"> </div>
|
|
302
|
+
<div className="w-full">
|
|
303
|
+
<RichTextarea
|
|
304
|
+
ref={field}
|
|
305
|
+
value={text.content}
|
|
306
|
+
style={{ width: "100%" }} // tailwind w-full does not work
|
|
307
|
+
className="order-none h-[150px] resize-none p-2 outline-none"
|
|
308
|
+
onChange={(e) => {
|
|
309
|
+
onChange(e.target.value)
|
|
310
|
+
}}
|
|
311
|
+
>
|
|
312
|
+
{(value) => {
|
|
313
|
+
// Get all styling indices
|
|
314
|
+
let indices = text.stylings
|
|
315
|
+
.map(({ start, finish }) => [start, finish])
|
|
316
|
+
.flat()
|
|
317
|
+
|
|
318
|
+
// Sort ascendingly
|
|
319
|
+
indices = indices.sort((a, b) => a - b)
|
|
320
|
+
|
|
321
|
+
// Remove duplicates
|
|
322
|
+
indices = indices.filter(
|
|
323
|
+
(element, index) => indices.indexOf(element) == index
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
// Add first index if not present
|
|
327
|
+
if (indices[0] != 0) indices.unshift(0)
|
|
328
|
+
|
|
329
|
+
// Add last index if not present
|
|
330
|
+
let last = text.content.length
|
|
331
|
+
if (indices[indices.length - 1] != last) indices.push(last)
|
|
332
|
+
|
|
333
|
+
let result = []
|
|
334
|
+
|
|
335
|
+
for (let i = 0; i < indices.length - 1; i++) {
|
|
336
|
+
result.push([
|
|
337
|
+
indices[i],
|
|
338
|
+
value.substring(indices[i], indices[i + 1]),
|
|
339
|
+
])
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return result.map((_data, index) => {
|
|
343
|
+
let [start, data] = _data
|
|
344
|
+
|
|
345
|
+
// Get stylings encompassing an index within it's range
|
|
346
|
+
let stylings = getIntersectStylings(start)
|
|
347
|
+
|
|
348
|
+
return (
|
|
349
|
+
<span
|
|
350
|
+
key={index}
|
|
351
|
+
className={`${stylings
|
|
352
|
+
.map((styling) => styleClasses[styling.type])
|
|
353
|
+
.join(" ")}
|
|
354
|
+
`}
|
|
355
|
+
>
|
|
356
|
+
{data}
|
|
357
|
+
</span>
|
|
358
|
+
)
|
|
359
|
+
})
|
|
360
|
+
}}
|
|
361
|
+
</RichTextarea>
|
|
362
|
+
</div>
|
|
363
|
+
<div className="h-[1px] w-full bg-slate-600"> </div>
|
|
364
|
+
<button className="my-1 rounded bg-cyan-800 p-2 py-1 text-white">
|
|
365
|
+
Submit
|
|
366
|
+
</button>
|
|
367
|
+
</div>
|
|
368
|
+
)
|
|
369
|
+
}
|
package/src/elements/index.ts
CHANGED
|
@@ -31,6 +31,8 @@ export * from "./UsageCard"
|
|
|
31
31
|
export * from "./InvoiceAccordion"
|
|
32
32
|
export * from "./HawaDatepicker"
|
|
33
33
|
export * from "./UserFeedback"
|
|
34
|
+
export * from "./ArrowCarousel"
|
|
35
|
+
export * from "./FloatingComment"
|
|
34
36
|
// Inputs
|
|
35
37
|
export * from "./HawaTextField"
|
|
36
38
|
export * from "./HawaCardInput"
|
package/src/styles.css
CHANGED
|
@@ -660,6 +660,9 @@ video {
|
|
|
660
660
|
.z-50 {
|
|
661
661
|
z-index: 50;
|
|
662
662
|
}
|
|
663
|
+
.order-none {
|
|
664
|
+
order: 0;
|
|
665
|
+
}
|
|
663
666
|
.m-0 {
|
|
664
667
|
margin: 0px;
|
|
665
668
|
}
|
|
@@ -771,6 +774,9 @@ video {
|
|
|
771
774
|
.mr-40 {
|
|
772
775
|
margin-right: 10rem;
|
|
773
776
|
}
|
|
777
|
+
.mr-\[5px\] {
|
|
778
|
+
margin-right: 5px;
|
|
779
|
+
}
|
|
774
780
|
.mt-0 {
|
|
775
781
|
margin-top: 0px;
|
|
776
782
|
}
|
|
@@ -798,6 +804,9 @@ video {
|
|
|
798
804
|
.mt-8 {
|
|
799
805
|
margin-top: 2rem;
|
|
800
806
|
}
|
|
807
|
+
.box-border {
|
|
808
|
+
box-sizing: border-box;
|
|
809
|
+
}
|
|
801
810
|
.block {
|
|
802
811
|
display: block;
|
|
803
812
|
}
|
|
@@ -882,12 +891,18 @@ video {
|
|
|
882
891
|
.h-96 {
|
|
883
892
|
height: 24rem;
|
|
884
893
|
}
|
|
894
|
+
.h-\[150px\] {
|
|
895
|
+
height: 150px;
|
|
896
|
+
}
|
|
885
897
|
.h-\[1px\] {
|
|
886
898
|
height: 1px;
|
|
887
899
|
}
|
|
888
900
|
.h-\[2\.36rem\] {
|
|
889
901
|
height: 2.36rem;
|
|
890
902
|
}
|
|
903
|
+
.h-\[32px\] {
|
|
904
|
+
height: 32px;
|
|
905
|
+
}
|
|
891
906
|
.h-\[calc\(100\%-3\.5rem\)\] {
|
|
892
907
|
height: calc(100% - 3.5rem);
|
|
893
908
|
}
|
|
@@ -901,6 +916,10 @@ video {
|
|
|
901
916
|
.h-full {
|
|
902
917
|
height: 100%;
|
|
903
918
|
}
|
|
919
|
+
.h-min {
|
|
920
|
+
height: -moz-min-content;
|
|
921
|
+
height: min-content;
|
|
922
|
+
}
|
|
904
923
|
.h-screen {
|
|
905
924
|
height: 100vh;
|
|
906
925
|
}
|
|
@@ -983,6 +1002,12 @@ video {
|
|
|
983
1002
|
.w-8 {
|
|
984
1003
|
width: 2rem;
|
|
985
1004
|
}
|
|
1005
|
+
.w-\[32px\] {
|
|
1006
|
+
width: 32px;
|
|
1007
|
+
}
|
|
1008
|
+
.w-\[400px\] {
|
|
1009
|
+
width: 400px;
|
|
1010
|
+
}
|
|
986
1011
|
.w-\[calc\(1\%\)\] {
|
|
987
1012
|
width: calc(1%);
|
|
988
1013
|
}
|
|
@@ -996,6 +1021,10 @@ video {
|
|
|
996
1021
|
.w-full {
|
|
997
1022
|
width: 100%;
|
|
998
1023
|
}
|
|
1024
|
+
.w-min {
|
|
1025
|
+
width: -moz-min-content;
|
|
1026
|
+
width: min-content;
|
|
1027
|
+
}
|
|
999
1028
|
.min-w-\[24px\] {
|
|
1000
1029
|
min-width: 24px;
|
|
1001
1030
|
}
|
|
@@ -1093,6 +1122,9 @@ video {
|
|
|
1093
1122
|
.cursor-pointer {
|
|
1094
1123
|
cursor: pointer;
|
|
1095
1124
|
}
|
|
1125
|
+
.resize-none {
|
|
1126
|
+
resize: none;
|
|
1127
|
+
}
|
|
1096
1128
|
.resize {
|
|
1097
1129
|
resize: both;
|
|
1098
1130
|
}
|
|
@@ -1481,6 +1513,10 @@ video {
|
|
|
1481
1513
|
.bg-buttonPrimary-500 {
|
|
1482
1514
|
background-color: var(--button-primary-500);
|
|
1483
1515
|
}
|
|
1516
|
+
.bg-cyan-800 {
|
|
1517
|
+
--tw-bg-opacity: 1;
|
|
1518
|
+
background-color: rgb(21 94 117 / var(--tw-bg-opacity));
|
|
1519
|
+
}
|
|
1484
1520
|
.bg-gray-100 {
|
|
1485
1521
|
--tw-bg-opacity: 1;
|
|
1486
1522
|
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
@@ -1493,6 +1529,10 @@ video {
|
|
|
1493
1529
|
--tw-bg-opacity: 1;
|
|
1494
1530
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
|
1495
1531
|
}
|
|
1532
|
+
.bg-gray-400 {
|
|
1533
|
+
--tw-bg-opacity: 1;
|
|
1534
|
+
background-color: rgb(156 163 175 / var(--tw-bg-opacity));
|
|
1535
|
+
}
|
|
1496
1536
|
.bg-gray-50 {
|
|
1497
1537
|
--tw-bg-opacity: 1;
|
|
1498
1538
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
|
@@ -1555,6 +1595,10 @@ video {
|
|
|
1555
1595
|
--tw-bg-opacity: 1;
|
|
1556
1596
|
background-color: rgb(185 28 28 / var(--tw-bg-opacity));
|
|
1557
1597
|
}
|
|
1598
|
+
.bg-slate-600 {
|
|
1599
|
+
--tw-bg-opacity: 1;
|
|
1600
|
+
background-color: rgb(71 85 105 / var(--tw-bg-opacity));
|
|
1601
|
+
}
|
|
1558
1602
|
.bg-transparent {
|
|
1559
1603
|
background-color: transparent;
|
|
1560
1604
|
}
|
|
@@ -1687,6 +1731,10 @@ video {
|
|
|
1687
1731
|
padding-top: 1.25rem;
|
|
1688
1732
|
padding-bottom: 1.25rem;
|
|
1689
1733
|
}
|
|
1734
|
+
.py-6 {
|
|
1735
|
+
padding-top: 1.5rem;
|
|
1736
|
+
padding-bottom: 1.5rem;
|
|
1737
|
+
}
|
|
1690
1738
|
.pb-2 {
|
|
1691
1739
|
padding-bottom: 0.5rem;
|
|
1692
1740
|
}
|
|
@@ -1797,6 +1845,9 @@ video {
|
|
|
1797
1845
|
.capitalize {
|
|
1798
1846
|
text-transform: capitalize;
|
|
1799
1847
|
}
|
|
1848
|
+
.italic {
|
|
1849
|
+
font-style: italic;
|
|
1850
|
+
}
|
|
1800
1851
|
.leading-4 {
|
|
1801
1852
|
line-height: 1rem;
|
|
1802
1853
|
}
|
|
@@ -1885,6 +1936,10 @@ video {
|
|
|
1885
1936
|
-webkit-text-decoration-line: underline;
|
|
1886
1937
|
text-decoration-line: underline;
|
|
1887
1938
|
}
|
|
1939
|
+
.line-through {
|
|
1940
|
+
-webkit-text-decoration-line: line-through;
|
|
1941
|
+
text-decoration-line: line-through;
|
|
1942
|
+
}
|
|
1888
1943
|
.underline-offset-4 {
|
|
1889
1944
|
text-underline-offset: 4px;
|
|
1890
1945
|
}
|
|
@@ -1930,6 +1985,10 @@ video {
|
|
|
1930
1985
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
1931
1986
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
1932
1987
|
}
|
|
1988
|
+
.outline-none {
|
|
1989
|
+
outline: 2px solid transparent;
|
|
1990
|
+
outline-offset: 2px;
|
|
1991
|
+
}
|
|
1933
1992
|
.outline {
|
|
1934
1993
|
outline-style: solid;
|
|
1935
1994
|
}
|
|
@@ -2178,6 +2237,11 @@ body {
|
|
|
2178
2237
|
color: rgb(156 163 175 / var(--tw-text-opacity));
|
|
2179
2238
|
}
|
|
2180
2239
|
|
|
2240
|
+
.hover\:text-gray-500:hover {
|
|
2241
|
+
--tw-text-opacity: 1;
|
|
2242
|
+
color: rgb(107 114 128 / var(--tw-text-opacity));
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2181
2245
|
.hover\:text-gray-900:hover {
|
|
2182
2246
|
--tw-text-opacity: 1;
|
|
2183
2247
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
|
@@ -2592,4 +2656,4 @@ body {
|
|
|
2592
2656
|
margin-left: 2.5rem;
|
|
2593
2657
|
margin-right: 2.5rem;
|
|
2594
2658
|
}
|
|
2595
|
-
}
|
|
2659
|
+
}
|
package/src/tailwind.css
CHANGED