chore(input): emoji button
This commit is contained in:
parent
9ae95efe17
commit
5fcae92532
11 changed files with 588 additions and 34 deletions
|
@ -73,6 +73,7 @@
|
|||
"react-dom": "^18.2.0",
|
||||
"rimraf": "^5.0.1",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"typescript": "^5.1.6",
|
||||
"unplugin-icons": "^0.16.5",
|
||||
"vite": "^4.4.3",
|
||||
|
@ -88,6 +89,7 @@
|
|||
"@radix-ui/react-avatar": "^1.0.3",
|
||||
"@radix-ui/react-hover-card": "^1.0.6",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-popover": "^1.0.7",
|
||||
"@radix-ui/react-scroll-area": "^1.0.4",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@tailwindcss/typography": "^0.5.9",
|
||||
|
|
282
pnpm-lock.yaml
282
pnpm-lock.yaml
|
@ -17,6 +17,9 @@ dependencies:
|
|||
'@radix-ui/react-icons':
|
||||
specifier: ^1.3.0
|
||||
version: 1.3.0(react@18.2.0)
|
||||
'@radix-ui/react-popover':
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-scroll-area':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
@ -175,6 +178,9 @@ devDependencies:
|
|||
tailwindcss:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2(ts-node@10.9.1)
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.3.2)
|
||||
typescript:
|
||||
specifier: ^5.1.6
|
||||
version: 5.1.6
|
||||
|
@ -1217,6 +1223,68 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.14)(react@18.2.0)
|
||||
'@types/react': 18.2.14
|
||||
'@types/react-dom': 18.2.7
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@types/react': 18.2.14
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@types/react': 18.2.14
|
||||
'@types/react-dom': 18.2.7
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-hover-card@1.0.6(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-2K3ToJuMk9wjwBOa+jdg2oPma+AmLdcEyTNsG/iC4BDVG3E0/mGCjbY8PEDSLxJcUi+nJi2QII+ec/4kWd88DA==}
|
||||
peerDependencies:
|
||||
|
@ -1254,6 +1322,56 @@ packages:
|
|||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-id@1.0.1(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@types/react': 18.2.14
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/primitive': 1.0.1
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-id': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@types/react': 18.2.14
|
||||
'@types/react-dom': 18.2.7
|
||||
aria-hidden: 1.2.3
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-remove-scroll: 2.5.5(@types/react@18.2.14)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==}
|
||||
peerDependencies:
|
||||
|
@ -1284,6 +1402,36 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@floating-ui/react-dom': 2.0.1(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-context': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.14)(react@18.2.0)
|
||||
'@radix-ui/rect': 1.0.1
|
||||
'@types/react': 18.2.14
|
||||
'@types/react-dom': 18.2.7
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==}
|
||||
peerDependencies:
|
||||
|
@ -1305,6 +1453,27 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
'@types/react-dom': '*'
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
'@types/react-dom':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.21.0
|
||||
'@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@types/react': 18.2.14
|
||||
'@types/react-dom': 18.2.7
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.7)(@types/react@18.2.14)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||
peerDependencies:
|
||||
|
@ -2009,6 +2178,13 @@ packages:
|
|||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/aria-hidden@1.2.3:
|
||||
resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/array-buffer-byte-length@1.0.0:
|
||||
resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==}
|
||||
dependencies:
|
||||
|
@ -2980,6 +3156,10 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/detect-node-es@1.1.0:
|
||||
resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
|
||||
dev: false
|
||||
|
||||
/devlop@1.1.0:
|
||||
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
|
||||
dependencies:
|
||||
|
@ -3978,6 +4158,11 @@ packages:
|
|||
has-symbols: 1.0.3
|
||||
dev: true
|
||||
|
||||
/get-nonce@1.0.1:
|
||||
resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/get-stream@5.2.0:
|
||||
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -4413,6 +4598,12 @@ packages:
|
|||
side-channel: 1.0.4
|
||||
dev: true
|
||||
|
||||
/invariant@2.2.4:
|
||||
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
dev: false
|
||||
|
||||
/invert-kv@3.0.1:
|
||||
resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -6561,6 +6752,58 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/react-remove-scroll-bar@2.3.4(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.14
|
||||
react: 18.2.0
|
||||
react-style-singleton: 2.2.1(@types/react@18.2.14)(react@18.2.0)
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/react-remove-scroll@2.5.5(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.14
|
||||
react: 18.2.0
|
||||
react-remove-scroll-bar: 2.3.4(@types/react@18.2.14)(react@18.2.0)
|
||||
react-style-singleton: 2.2.1(@types/react@18.2.14)(react@18.2.0)
|
||||
tslib: 2.6.0
|
||||
use-callback-ref: 1.3.0(@types/react@18.2.14)(react@18.2.0)
|
||||
use-sidecar: 1.1.2(@types/react@18.2.14)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-style-singleton@2.2.1(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.14
|
||||
get-nonce: 1.0.1
|
||||
invariant: 2.2.4
|
||||
react: 18.2.0
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/react-universal-interface@0.6.2(react@18.2.0)(tslib@2.6.0):
|
||||
resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==}
|
||||
peerDependencies:
|
||||
|
@ -7542,6 +7785,14 @@ packages:
|
|||
resolution: {integrity: sha512-R2/nULkdg1VR/EL4RXg4dEohdoxNUJGLMnWIQnPKL+O9Twu7Cn3Rxi4dlXkDzZrEGtR+G+psSXFouWlpTyLhCQ==}
|
||||
dev: false
|
||||
|
||||
/tailwindcss-animate@1.0.7(tailwindcss@3.3.2):
|
||||
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
|
||||
peerDependencies:
|
||||
tailwindcss: '>=3.0.0 || insiders'
|
||||
dependencies:
|
||||
tailwindcss: 3.3.2(ts-node@10.9.1)
|
||||
dev: true
|
||||
|
||||
/tailwindcss@3.3.2(ts-node@10.9.1):
|
||||
resolution: {integrity: sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
@ -8034,6 +8285,37 @@ packages:
|
|||
punycode: 2.3.0
|
||||
dev: true
|
||||
|
||||
/use-callback-ref@1.3.0(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.14
|
||||
react: 18.2.0
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/use-sidecar@1.1.2(@types/react@18.2.14)(react@18.2.0):
|
||||
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.14
|
||||
detect-node-es: 1.1.0
|
||||
react: 18.2.0
|
||||
tslib: 2.6.0
|
||||
dev: false
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
|
|
58
src/components/EmojiButton.tsx
Normal file
58
src/components/EmojiButton.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { SmileIcon } from 'lucide-react'
|
||||
import { useState, type FC } from 'react'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover'
|
||||
import { ScrollArea } from '@/components/ui/ScrollArea'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import { EMOJI_LIST } from '@/constants'
|
||||
import { chunk } from '@/utils'
|
||||
|
||||
export interface EmojiButtonProps {
|
||||
onSelect?: (value: string) => void
|
||||
}
|
||||
|
||||
const emojiGroups = chunk(EMOJI_LIST, 8)
|
||||
|
||||
// BUG: https://github.com/radix-ui/primitives/pull/2433
|
||||
// BUG https://github.com/radix-ui/primitives/issues/1666
|
||||
const EmojiButton: FC<EmojiButtonProps> = ({ onSelect }) => {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const handleSelect = (value: string) => {
|
||||
onSelect?.(value)
|
||||
setOpen(false)
|
||||
}
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<SmileIcon size={20} />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="z-top w-72 px-0">
|
||||
<ScrollArea className="h-72 w-72 px-3">
|
||||
{emojiGroups.map((group, index) => {
|
||||
return (
|
||||
<div key={index} className="grid grid-cols-8">
|
||||
{group.map((emoji, index) => (
|
||||
<Button
|
||||
key={index}
|
||||
size="sm"
|
||||
className="text-base"
|
||||
variant="ghost"
|
||||
onClick={() => handleSelect(emoji)}
|
||||
>
|
||||
{emoji}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</ScrollArea>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
|
||||
EmojiButton.displayName = 'EmojiButton'
|
||||
|
||||
export default EmojiButton
|
|
@ -23,14 +23,14 @@ const LikeButton: FC<LikeButtonProps> & { Icon: FC<LikeButtonIconProps> } = ({
|
|||
onChange,
|
||||
children
|
||||
}) => {
|
||||
const handleOnClick = (e: MouseEvent<HTMLButtonElement>) => {
|
||||
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
|
||||
onClick?.(e)
|
||||
onChange?.(!checked, checked ? count - 1 : count + 1)
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
onClick={handleOnClick}
|
||||
onClick={handleClick}
|
||||
variant="secondary"
|
||||
className={cn(
|
||||
'grid items-center overflow-hidden rounded-full leading-none transition-all',
|
||||
|
|
31
src/components/ui/Popover.tsx
Normal file
31
src/components/ui/Popover.tsx
Normal file
|
@ -0,0 +1,31 @@
|
|||
import * as React from 'react'
|
||||
import * as PopoverPrimitive from '@radix-ui/react-popover'
|
||||
import { cn } from '@/utils/index'
|
||||
|
||||
const Popover = PopoverPrimitive.Root
|
||||
|
||||
const PopoverTrigger = PopoverPrimitive.Trigger
|
||||
|
||||
const PopoverContent = React.forwardRef<
|
||||
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => {
|
||||
const shadowRoot = document.querySelector(__NAME__)!.shadowRoot! as any as HTMLElement
|
||||
return (
|
||||
<PopoverPrimitive.Portal container={shadowRoot}>
|
||||
<PopoverPrimitive.Content
|
||||
ref={ref}
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
></PopoverPrimitive.Content>
|
||||
</PopoverPrimitive.Portal>
|
||||
)
|
||||
})
|
||||
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
||||
|
||||
export { Popover, PopoverTrigger, PopoverContent }
|
|
@ -1,3 +1,169 @@
|
|||
// https://www.webfx.com/tools/emoji-cheat-sheet/
|
||||
export const EMOJI_LIST = [
|
||||
'😀',
|
||||
'😃',
|
||||
'😄',
|
||||
'😁',
|
||||
'😆',
|
||||
'😅',
|
||||
'🤣',
|
||||
'😂',
|
||||
'🙂',
|
||||
'🙃',
|
||||
'🫠',
|
||||
'😉',
|
||||
'😊',
|
||||
'😇',
|
||||
'🥰',
|
||||
'😍',
|
||||
'🤩',
|
||||
'😘',
|
||||
'😗',
|
||||
'😚',
|
||||
'😙',
|
||||
'🥲',
|
||||
'😋',
|
||||
'😛',
|
||||
'😜',
|
||||
'🤪',
|
||||
'😝',
|
||||
'🤑',
|
||||
'🤗',
|
||||
'🤭',
|
||||
'🫢',
|
||||
'🫣',
|
||||
'🤫',
|
||||
'🤔',
|
||||
'🫡',
|
||||
'🤐',
|
||||
'🤨',
|
||||
'😐',
|
||||
'😶',
|
||||
'🫥',
|
||||
'😶🌫️',
|
||||
'😏',
|
||||
'😒',
|
||||
'🙄',
|
||||
'😬',
|
||||
'😮💨',
|
||||
'🤥',
|
||||
'😌',
|
||||
'😔',
|
||||
'😪',
|
||||
'🤤',
|
||||
'😴',
|
||||
'😷',
|
||||
'🤒',
|
||||
'🤕',
|
||||
'🤢',
|
||||
'🤮',
|
||||
'🤧',
|
||||
'🥵',
|
||||
'🥶',
|
||||
'🥴',
|
||||
'😵',
|
||||
'😵💫',
|
||||
'🤯',
|
||||
'🤠',
|
||||
'🥳',
|
||||
'🥸',
|
||||
'😎',
|
||||
'🤓',
|
||||
'🧐',
|
||||
'😕',
|
||||
'🫤',
|
||||
'😟',
|
||||
'🙁',
|
||||
'😮',
|
||||
'😯',
|
||||
'😲',
|
||||
'😳',
|
||||
'🥺',
|
||||
'🥹',
|
||||
'😦',
|
||||
'😧',
|
||||
'😨',
|
||||
'😰',
|
||||
'😥',
|
||||
'😢',
|
||||
'😭',
|
||||
'😱',
|
||||
'😖',
|
||||
'😣',
|
||||
'😞',
|
||||
'😓',
|
||||
'😩',
|
||||
'😫',
|
||||
'🥱',
|
||||
'😤',
|
||||
'😡',
|
||||
'😠',
|
||||
'🤬',
|
||||
'😈',
|
||||
'👿',
|
||||
'💀',
|
||||
'☠',
|
||||
'💩',
|
||||
'🤡',
|
||||
'👹',
|
||||
'👺',
|
||||
'👻',
|
||||
'👽',
|
||||
'👾',
|
||||
'🤖',
|
||||
'😺',
|
||||
'😸',
|
||||
'😹',
|
||||
'😻',
|
||||
'😼',
|
||||
'😽',
|
||||
'🙀',
|
||||
'😿',
|
||||
'😾',
|
||||
'🙈',
|
||||
'🙉',
|
||||
'🙊',
|
||||
'👋',
|
||||
'🤚',
|
||||
'🖐',
|
||||
'✋',
|
||||
'🖖',
|
||||
'🫱',
|
||||
'🫲',
|
||||
'🫳',
|
||||
'🫴',
|
||||
'👌',
|
||||
'🤏',
|
||||
'✌',
|
||||
'🤞',
|
||||
'🫰',
|
||||
'🤟',
|
||||
'🤘',
|
||||
'🤙',
|
||||
'👈',
|
||||
'👉',
|
||||
'👆',
|
||||
'🖕',
|
||||
'👇',
|
||||
'☝',
|
||||
'🫵',
|
||||
'👍',
|
||||
'👎',
|
||||
'✊',
|
||||
'👊',
|
||||
'🤛',
|
||||
'🤜',
|
||||
'👏',
|
||||
'🙌',
|
||||
'🫶',
|
||||
'👐',
|
||||
'🤲',
|
||||
'🤝',
|
||||
'🙏',
|
||||
'✍',
|
||||
'💅'
|
||||
]
|
||||
|
||||
// https://night-tailwindcss.vercel.app/docs/breakpoints
|
||||
export const BREAKPOINTS = {
|
||||
sm: 640,
|
||||
|
|
|
@ -9,7 +9,10 @@ export interface RootOptions {
|
|||
element?: Element
|
||||
}
|
||||
|
||||
const createShadowRoot = (name: string, options: RootOptions): Root => {
|
||||
const createShadowRoot = (
|
||||
name: string,
|
||||
options: RootOptions
|
||||
): Root & { shadowHost: Element; shadowRoot: ShadowRoot; appRoot: Element } => {
|
||||
const { mode = 'open', style = '', script = '', element = '' } = options ?? {}
|
||||
const shadowHost = createElement(`<${name}></${name}>`)
|
||||
const shadowRoot = shadowHost.attachShadow({ mode })
|
||||
|
@ -21,10 +24,16 @@ const createShadowRoot = (name: string, options: RootOptions): Root => {
|
|||
shadowRoot.append(appStyle, appRoot, appScript, element)
|
||||
|
||||
return {
|
||||
...reactRoot,
|
||||
shadowHost,
|
||||
shadowRoot,
|
||||
appRoot,
|
||||
render: (children: ReactNode) => {
|
||||
document.body.appendChild(shadowHost)
|
||||
reactRoot.render(children)
|
||||
return reactRoot.render(children)
|
||||
},
|
||||
unmount: () => {
|
||||
reactRoot.unmount()
|
||||
shadowHost.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
25
src/main.tsx
25
src/main.tsx
|
@ -7,29 +7,28 @@ import createShadowRoot from './createShadowRoot'
|
|||
import StorageImpl from './impl/Storage'
|
||||
import style from './index.css?inline'
|
||||
|
||||
void (async () => {
|
||||
const store = Remesh.store({
|
||||
const store = Remesh.store({
|
||||
externs: [StorageImpl],
|
||||
inspectors: [RemeshLogger()]
|
||||
})
|
||||
})
|
||||
|
||||
createShadowRoot(__NAME__, {
|
||||
const root = createShadowRoot(__NAME__, {
|
||||
style: __DEV__ ? '' : style,
|
||||
mode: __DEV__ ? 'open' : 'closed'
|
||||
}).render(
|
||||
})
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<RemeshRoot store={store}>
|
||||
<App />
|
||||
</RemeshRoot>
|
||||
</React.StrictMode>
|
||||
)
|
||||
)
|
||||
|
||||
// HMR Hack
|
||||
// https://github.com/crxjs/chrome-extension-tools/issues/600
|
||||
if (__DEV__) {
|
||||
// HMR Hack
|
||||
// https://github.com/crxjs/chrome-extension-tools/issues/600
|
||||
if (__DEV__) {
|
||||
await import('./index.css')
|
||||
const styleElement = document.querySelector('[data-vite-dev-id]')!
|
||||
const shadowRoot = document.querySelector(__NAME__)!.shadowRoot!
|
||||
shadowRoot.insertBefore(styleElement, shadowRoot.firstChild)
|
||||
}
|
||||
})()
|
||||
|
||||
root.shadowRoot.insertBefore(styleElement, root.shadowRoot.firstChild)
|
||||
}
|
||||
|
|
|
@ -8,3 +8,6 @@ export const cn = (...inputs: ClassValue[]) => {
|
|||
export const createElement = <T extends Element>(template: string) => {
|
||||
return new Range().createContextualFragment(template).firstElementChild as unknown as T
|
||||
}
|
||||
|
||||
export const chunk = <T = any>(array: T[], size: number) =>
|
||||
Array.from({ length: Math.ceil(array.length / size) }, (_v, i) => array.slice(i * size, i * size + size))
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { type FC } from 'react'
|
||||
import { SmileIcon, CornerDownLeftIcon, ImageIcon } from 'lucide-react'
|
||||
import { CornerDownLeftIcon, ImageIcon } from 'lucide-react'
|
||||
import { useRemeshDomain, useRemeshQuery, useRemeshSend } from 'remesh-react'
|
||||
import { Button } from '@/components/ui/Button'
|
||||
import MessageInput from '@/components/MessageInput'
|
||||
import MessageInputDomain from '@/domain/MessageInput'
|
||||
import MessageListDomain from '@/domain/MessageList'
|
||||
import { MESSAGE_MAX_LENGTH } from '@/constants'
|
||||
import EmojiButton from '@/components/EmojiButton'
|
||||
|
||||
const Footer: FC = () => {
|
||||
const send = useRemeshSend()
|
||||
|
@ -33,6 +34,10 @@ const Footer: FC = () => {
|
|||
send(messageInputDomain.command.ClearCommand())
|
||||
}
|
||||
|
||||
const handleEmojiSelect = (value: string) => {
|
||||
send(messageInputDomain.command.InputCommand(messageText + value))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid gap-y-2 px-4 pb-4">
|
||||
<MessageInput
|
||||
|
@ -42,9 +47,7 @@ const Footer: FC = () => {
|
|||
maxLength={MESSAGE_MAX_LENGTH}
|
||||
></MessageInput>
|
||||
<div className="grid grid-cols-[auto_auto_1fr] items-center justify-items-end">
|
||||
<Button variant="ghost" size="icon">
|
||||
<SmileIcon size={20} />
|
||||
</Button>
|
||||
<EmojiButton onSelect={handleEmojiSelect}></EmojiButton>
|
||||
<Button variant="ghost" size="icon">
|
||||
<ImageIcon size={20} />
|
||||
</Button>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { type Config } from 'tailwindcss'
|
||||
import typography from '@tailwindcss/typography'
|
||||
import animate from 'tailwindcss-animate'
|
||||
|
||||
export default {
|
||||
darkMode: ['class'],
|
||||
|
@ -69,5 +70,5 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
plugins: [typography()]
|
||||
plugins: [animate, typography()]
|
||||
} satisfies Config
|
||||
|
|
Loading…
Reference in a new issue