playbook_ui 14.17.0.pre.alpha.PBNTR920emojipickerpoc7143 → 14.17.0.pre.alpha.PBNTR925railstablecustomheaders7161
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.
- checksums.yaml +4 -4
- data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless.html.erb +34 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless_rails.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating.html.erb +36 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating_rails.md +1 -0
- data/app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating_react.md +1 -1
- data/app/pb_kits/playbook/pb_table/docs/example.yml +2 -0
- data/app/pb_kits/playbook/pb_table/table.rb +13 -1
- data/app/pb_kits/playbook/pb_table/table_header.rb +13 -1
- data/app/pb_kits/playbook/pb_text_input/docs/example.yml +0 -1
- data/app/pb_kits/playbook/pb_text_input/docs/index.js +0 -1
- data/dist/playbook-doc.js +1 -1
- data/lib/playbook/version.rb +1 -1
- metadata +6 -3
- data/app/pb_kits/playbook/pb_text_input/docs/_text_input_emoji_picker.jsx +0 -371
data/lib/playbook/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: playbook_ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 14.17.0.pre.alpha.
|
4
|
+
version: 14.17.0.pre.alpha.PBNTR925railstablecustomheaders7161
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Power UX
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2025-04-
|
12
|
+
date: 2025-04-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -2867,9 +2867,13 @@ files:
|
|
2867
2867
|
- app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table.md
|
2868
2868
|
- app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.html.erb
|
2869
2869
|
- app/pb_kits/playbook/pb_table/docs/_table_with_collapsible_with_nested_table_rails.md
|
2870
|
+
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless.html.erb
|
2870
2871
|
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless.jsx
|
2872
|
+
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless_rails.md
|
2871
2873
|
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_borderless_react.md
|
2874
|
+
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating.html.erb
|
2872
2875
|
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating.jsx
|
2876
|
+
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating_rails.md
|
2873
2877
|
- app/pb_kits/playbook/pb_table/docs/_table_with_header_style_floating_react.md
|
2874
2878
|
- app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.html.erb
|
2875
2879
|
- app/pb_kits/playbook/pb_table/docs/_table_with_selectable_rows.jsx
|
@@ -2945,7 +2949,6 @@ files:
|
|
2945
2949
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_disabled.html.erb
|
2946
2950
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_disabled.jsx
|
2947
2951
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_disabled_swift.md
|
2948
|
-
- app/pb_kits/playbook/pb_text_input/docs/_text_input_emoji_picker.jsx
|
2949
2952
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_error.html.erb
|
2950
2953
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_error.jsx
|
2951
2954
|
- app/pb_kits/playbook/pb_text_input/docs/_text_input_error.md
|
@@ -1,371 +0,0 @@
|
|
1
|
-
import React, { useState, useEffect } from "react"
|
2
|
-
import TextInput from '../../pb_text_input/_text_input'
|
3
|
-
import Button from "../../pb_button/_button"
|
4
|
-
|
5
|
-
// Emojis organized by category with icons for navigation and search names
|
6
|
-
const emojiCategories = [
|
7
|
-
{
|
8
|
-
id: 'recent',
|
9
|
-
name: "Recent",
|
10
|
-
icon: '🕒',
|
11
|
-
emojis: [
|
12
|
-
{ emoji: '😀', name: 'happy' },
|
13
|
-
{ emoji: '👍', name: 'thumbs up' },
|
14
|
-
{ emoji: '🎉', name: 'popper' },
|
15
|
-
{ emoji: '❤️', name: 'heart' },
|
16
|
-
{ emoji: '🔥', name: 'fire' },
|
17
|
-
{ emoji: '✨', name: 'sparkles' }
|
18
|
-
]
|
19
|
-
},
|
20
|
-
{
|
21
|
-
id: 'smileys',
|
22
|
-
name: "Smileys",
|
23
|
-
icon: '😊',
|
24
|
-
emojis: [
|
25
|
-
{ emoji: '😀', name: 'happy' },
|
26
|
-
{ emoji: '😂', name: 'lmao' },
|
27
|
-
{ emoji: '🙂', name: 'smile' },
|
28
|
-
{ emoji: '😊', name: 'smiley' },
|
29
|
-
{ emoji: '😍', name: 'smile-heart' },
|
30
|
-
{ emoji: '🤩', name: 'star-struck' }
|
31
|
-
]
|
32
|
-
},
|
33
|
-
{
|
34
|
-
id: 'people',
|
35
|
-
name: "People",
|
36
|
-
icon: '👥',
|
37
|
-
emojis: [
|
38
|
-
{ emoji: '👍', name: 'thumbs up' },
|
39
|
-
{ emoji: '👎', name: 'thumbs down' },
|
40
|
-
{ emoji: '👌', name: 'OK' },
|
41
|
-
{ emoji: '👋', name: 'wave' },
|
42
|
-
{ emoji: '✌️', name: 'victory' },
|
43
|
-
{ emoji: '🙏', name: 'pray' }
|
44
|
-
]
|
45
|
-
},
|
46
|
-
{
|
47
|
-
id: 'animals',
|
48
|
-
name: "Animals",
|
49
|
-
icon: '🐼',
|
50
|
-
emojis: [
|
51
|
-
{ emoji: '🐶', name: 'dog' },
|
52
|
-
{ emoji: '🐱', name: 'cat' },
|
53
|
-
{ emoji: '🐼', name: 'panda' },
|
54
|
-
{ emoji: '🦁', name: 'lion' },
|
55
|
-
{ emoji: '🐢', name: 'turtle' },
|
56
|
-
{ emoji: '🦋', name: 'butterfly' }
|
57
|
-
]
|
58
|
-
},
|
59
|
-
{
|
60
|
-
id: 'food',
|
61
|
-
name: "Food",
|
62
|
-
icon: '🍔',
|
63
|
-
emojis: [
|
64
|
-
{ emoji: '🍎', name: 'apple' },
|
65
|
-
{ emoji: '🍕', name: 'pizza' },
|
66
|
-
{ emoji: '🍦', name: 'ice cream' },
|
67
|
-
{ emoji: '🍩', name: 'doughnut' },
|
68
|
-
{ emoji: '🍷', name: 'wine' },
|
69
|
-
{ emoji: '🍺', name: 'beer' }
|
70
|
-
]
|
71
|
-
},
|
72
|
-
{
|
73
|
-
id: 'activities',
|
74
|
-
name: "Activities",
|
75
|
-
icon: '⚽',
|
76
|
-
emojis: [
|
77
|
-
{ emoji: '⚽', name: 'soccer ball' },
|
78
|
-
{ emoji: '🏀', name: 'basketball' },
|
79
|
-
{ emoji: '🎮', name: 'video game' },
|
80
|
-
{ emoji: '🎬', name: 'clapper board' },
|
81
|
-
{ emoji: '🎨', name: 'artist palette' },
|
82
|
-
{ emoji: '🎭', name: 'performing arts' }
|
83
|
-
]
|
84
|
-
},
|
85
|
-
{
|
86
|
-
id: 'travel',
|
87
|
-
name: "Travel",
|
88
|
-
icon: '✈️',
|
89
|
-
emojis: [
|
90
|
-
{ emoji: '🚗', name: 'automobile' },
|
91
|
-
{ emoji: '✈️', name: 'airplane' },
|
92
|
-
{ emoji: '🚲', name: 'bicycle' },
|
93
|
-
{ emoji: '⛵', name: 'sailboat' },
|
94
|
-
{ emoji: '🏖️', name: 'beach' },
|
95
|
-
{ emoji: '🗽', name: 'Statue of Liberty' }
|
96
|
-
]
|
97
|
-
},
|
98
|
-
{
|
99
|
-
id: 'symbols',
|
100
|
-
name: "Symbols",
|
101
|
-
icon: '🔣',
|
102
|
-
emojis: [
|
103
|
-
{ emoji: '❤️', name: 'heart' },
|
104
|
-
{ emoji: '🔥', name: 'fire' },
|
105
|
-
{ emoji: '✨', name: 'sparkles' },
|
106
|
-
{ emoji: '💯', name: 'hundred' },
|
107
|
-
{ emoji: '⭐', name: 'star' },
|
108
|
-
{ emoji: '💪', name: 'flex' }
|
109
|
-
]
|
110
|
-
}
|
111
|
-
]
|
112
|
-
|
113
|
-
const TextInputEmojiPicker = (props) => {
|
114
|
-
const [inputText, setInputText] = useState('')
|
115
|
-
const [showPicker, setShowPicker] = useState(false)
|
116
|
-
const [activeCategory, setActiveCategory] = useState('smileys')
|
117
|
-
const [searchQuery, setSearchQuery] = useState('')
|
118
|
-
const [filteredEmojis, setFilteredEmojis] = useState([])
|
119
|
-
const [recentEmojis, setRecentEmojis] = useState([
|
120
|
-
{ emoji: '😀', name: 'happy' },
|
121
|
-
{ emoji: '👍', name: 'thumbs up' },
|
122
|
-
{ emoji: '🎉', name: 'popper' },
|
123
|
-
{ emoji: '❤️', name: 'heart' },
|
124
|
-
{ emoji: '🔥', name: 'fire' },
|
125
|
-
{ emoji: '✨', name: 'sparkles' }
|
126
|
-
])
|
127
|
-
|
128
|
-
// Handle emoji selection
|
129
|
-
const handleEmojiClick = (emojiObj) => {
|
130
|
-
setInputText(prevInput => prevInput + emojiObj.emoji)
|
131
|
-
|
132
|
-
// Add to recent emojis
|
133
|
-
if (!recentEmojis.some(item => item.emoji === emojiObj.emoji)) {
|
134
|
-
const updatedRecent = [emojiObj, ...recentEmojis.slice(0, 5)]
|
135
|
-
setRecentEmojis(updatedRecent)
|
136
|
-
|
137
|
-
// Update the recent category
|
138
|
-
const recentCategory = emojiCategories.find(cat => cat.id === 'recent')
|
139
|
-
if (recentCategory) {
|
140
|
-
recentCategory.emojis = updatedRecent
|
141
|
-
}
|
142
|
-
}
|
143
|
-
|
144
|
-
// Uncomment to close picker after selection
|
145
|
-
// setShowPicker(false)
|
146
|
-
}
|
147
|
-
|
148
|
-
// Handle search
|
149
|
-
useEffect(() => {
|
150
|
-
if (searchQuery.trim() === '') {
|
151
|
-
setFilteredEmojis([])
|
152
|
-
return
|
153
|
-
}
|
154
|
-
|
155
|
-
// Collect all emojis and filter based on search
|
156
|
-
const allEmojis = emojiCategories.flatMap(category =>
|
157
|
-
category.emojis.map(emojiObj => ({
|
158
|
-
...emojiObj,
|
159
|
-
categoryName: category.name
|
160
|
-
}))
|
161
|
-
)
|
162
|
-
|
163
|
-
// Search by emoji name or category
|
164
|
-
const filtered = allEmojis.filter(item =>
|
165
|
-
item.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
166
|
-
item.categoryName.toLowerCase().includes(searchQuery.toLowerCase())
|
167
|
-
)
|
168
|
-
|
169
|
-
setFilteredEmojis(filtered)
|
170
|
-
}, [searchQuery])
|
171
|
-
|
172
|
-
return (
|
173
|
-
<div className="emoji-container">
|
174
|
-
<div className="input-wrapper">
|
175
|
-
<TextInput
|
176
|
-
id="emoji-text-input"
|
177
|
-
name="emojiPicker"
|
178
|
-
onChange={(e) => setInputText(e.target.value)}
|
179
|
-
placeholder="Enter some emojis here"
|
180
|
-
value={inputText}
|
181
|
-
{...props}
|
182
|
-
/>
|
183
|
-
<Button
|
184
|
-
className="emoji-toggle-button"
|
185
|
-
marginRight="lg"
|
186
|
-
onClick={() => setShowPicker(!showPicker)}
|
187
|
-
variant="link"
|
188
|
-
>
|
189
|
-
😊
|
190
|
-
</Button>
|
191
|
-
</div>
|
192
|
-
|
193
|
-
{showPicker && (
|
194
|
-
<div className="picker-wrapper">
|
195
|
-
{/* Search Bar */}
|
196
|
-
<TextInput
|
197
|
-
onChange={(e) => setSearchQuery(e.target.value)}
|
198
|
-
placeholder="Search emojis..."
|
199
|
-
type="text"
|
200
|
-
value={searchQuery}
|
201
|
-
{...props}
|
202
|
-
/>
|
203
|
-
|
204
|
-
{/* Category Navigation */}
|
205
|
-
<div className="category-nav">
|
206
|
-
{emojiCategories.map(category => (
|
207
|
-
<button
|
208
|
-
className={`category-button ${activeCategory === category.id ? 'active' : ''}`}
|
209
|
-
key={category.id}
|
210
|
-
onClick={() => {
|
211
|
-
setActiveCategory(category.id)
|
212
|
-
setSearchQuery('')
|
213
|
-
document.getElementById(`category-${category.id}`)?.scrollIntoView({ behavior: 'smooth' })
|
214
|
-
}}
|
215
|
-
title={category.name}
|
216
|
-
>
|
217
|
-
{category.icon}
|
218
|
-
</button>
|
219
|
-
))}
|
220
|
-
</div>
|
221
|
-
|
222
|
-
{/* Emoji Content */}
|
223
|
-
<div className="emoji-content">
|
224
|
-
{searchQuery.trim() !== '' ? (
|
225
|
-
// Search Results
|
226
|
-
<div className="search-results">
|
227
|
-
<div className="category-title">Search Results</div>
|
228
|
-
{filteredEmojis.length > 0 ? (
|
229
|
-
<div className="emoji-grid">
|
230
|
-
{filteredEmojis.map((item, index) => (
|
231
|
-
<Button
|
232
|
-
className="emoji-button"
|
233
|
-
key={`search-${index}`}
|
234
|
-
onClick={() => handleEmojiClick(item)}
|
235
|
-
title={item.name}
|
236
|
-
variant="link"
|
237
|
-
>
|
238
|
-
{item.emoji}
|
239
|
-
</Button>
|
240
|
-
))}
|
241
|
-
</div>
|
242
|
-
) : (
|
243
|
-
<div className="no-results">No emojis found</div>
|
244
|
-
)}
|
245
|
-
</div>
|
246
|
-
) : (
|
247
|
-
// All Categories
|
248
|
-
<div className="all-categories">
|
249
|
-
{emojiCategories.map(category => (
|
250
|
-
<div
|
251
|
-
className="category-section"
|
252
|
-
id={`category-${category.id}`}
|
253
|
-
key={category.id}
|
254
|
-
>
|
255
|
-
<div className="category-title">
|
256
|
-
{category.name}
|
257
|
-
</div>
|
258
|
-
<div className="emoji-grid">
|
259
|
-
{category.emojis.map((emojiObj, index) => (
|
260
|
-
<Button
|
261
|
-
className="emoji-button"
|
262
|
-
key={`${category.id}-${index}`}
|
263
|
-
onClick={() => handleEmojiClick(emojiObj)}
|
264
|
-
title={emojiObj.name}
|
265
|
-
variant="link"
|
266
|
-
>
|
267
|
-
{emojiObj.emoji}
|
268
|
-
</Button>
|
269
|
-
))}
|
270
|
-
</div>
|
271
|
-
</div>
|
272
|
-
))}
|
273
|
-
</div>
|
274
|
-
)}
|
275
|
-
</div>
|
276
|
-
</div>
|
277
|
-
)}
|
278
|
-
|
279
|
-
<style jsx>{`
|
280
|
-
.emoji-container {
|
281
|
-
font-family: Arial, sans-serif;
|
282
|
-
max-width: 500px;
|
283
|
-
position: relative;
|
284
|
-
}
|
285
|
-
|
286
|
-
.input-wrapper {
|
287
|
-
display: flex;
|
288
|
-
margin-bottom: 10px;
|
289
|
-
position: relative;
|
290
|
-
}
|
291
|
-
|
292
|
-
.picker-wrapper {
|
293
|
-
position: absolute;
|
294
|
-
z-index: 100;
|
295
|
-
margin-top: 5px;
|
296
|
-
background: white;
|
297
|
-
border: 1px solid #ddd;
|
298
|
-
border-radius: 8px;
|
299
|
-
padding: 12px;
|
300
|
-
box-shadow: 0 2px 15px rgba(0,0,0,0.1);
|
301
|
-
width: 320px;
|
302
|
-
}
|
303
|
-
|
304
|
-
.search-container {
|
305
|
-
margin-bottom: 12px;
|
306
|
-
}
|
307
|
-
|
308
|
-
.category-nav {
|
309
|
-
display: flex;
|
310
|
-
overflow-x: auto;
|
311
|
-
padding-bottom: 8px;
|
312
|
-
margin-bottom: 12px;
|
313
|
-
border-bottom: 1px solid #eee;
|
314
|
-
}
|
315
|
-
|
316
|
-
.category-button {
|
317
|
-
background: none;
|
318
|
-
border: none;
|
319
|
-
font-size: 18px;
|
320
|
-
padding: 8px;
|
321
|
-
cursor: pointer;
|
322
|
-
margin-right: 4px;
|
323
|
-
border-radius: 4px;
|
324
|
-
min-width: 36px;
|
325
|
-
}
|
326
|
-
|
327
|
-
.category-button.active {
|
328
|
-
background-color: #f0f0f0;
|
329
|
-
}
|
330
|
-
|
331
|
-
.emoji-content {
|
332
|
-
max-height: 300px;
|
333
|
-
overflow-y: auto;
|
334
|
-
scroll-behavior: smooth;
|
335
|
-
}
|
336
|
-
|
337
|
-
.all-categories {
|
338
|
-
display: flex;
|
339
|
-
flex-direction: column;
|
340
|
-
gap: 16px;
|
341
|
-
}
|
342
|
-
|
343
|
-
.category-section {
|
344
|
-
padding-top: 8px;
|
345
|
-
scroll-margin-top: 8px;
|
346
|
-
}
|
347
|
-
|
348
|
-
.category-title {
|
349
|
-
font-weight: bold;
|
350
|
-
margin-bottom: 8px;
|
351
|
-
color: #555;
|
352
|
-
font-size: 14px;
|
353
|
-
}
|
354
|
-
|
355
|
-
.emoji-grid {
|
356
|
-
display: grid;
|
357
|
-
grid-template-columns: repeat(6, 1fr);
|
358
|
-
gap: 2px;
|
359
|
-
}
|
360
|
-
|
361
|
-
.no-results {
|
362
|
-
padding: 20px;
|
363
|
-
text-align: center;
|
364
|
-
color: #999;
|
365
|
-
}
|
366
|
-
`}</style>
|
367
|
-
</div>
|
368
|
-
);
|
369
|
-
};
|
370
|
-
|
371
|
-
export default TextInputEmojiPicker
|