@react-ui-org/react-ui 0.63.1 → 0.64.1
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/.claude/agents/code-reviewer.md +122 -0
- package/.claude/rules/code.md +22 -0
- package/.claude/rules/docs.md +35 -0
- package/.claude/rules/frontend.md +72 -0
- package/.claude/rules/git.md +13 -0
- package/.claude/rules/safety-guards.md +9 -0
- package/.claude/rules/styling.md +32 -0
- package/.claude/rules/testing.md +59 -0
- package/.claude/settings.json +32 -0
- package/.claude/skills/commit/SKILL.md +54 -0
- package/.devcontainer/devcontainer.json +23 -0
- package/.mcp.json +8 -0
- package/CLAUDE.md +82 -0
- package/dist/react-ui.css +4 -4
- package/dist/react-ui.development.css +600 -590
- package/dist/react-ui.development.js +20 -10
- package/dist/react-ui.js +1 -1
- package/docker-compose.base.yml +93 -0
- package/docker-compose.yml.dist +41 -0
- package/opencode.json +10 -0
- package/package.json +3 -2
- package/scripts/auto-start-mkdocs.sh +5 -0
- package/scripts/auto-start-node.sh +33 -0
- package/scripts/mcps/chrome-host/README.md +118 -0
- package/scripts/mcps/chrome-host/cdp_proxy.py +90 -0
- package/scripts/mcps/chrome-host/mcp-entry.sh +33 -0
- package/scripts/mcps/chrome-host/mcp-launch.sh +36 -0
- package/scripts/mcps/chrome-host/mcp-setup.sh +70 -0
- package/scripts/mcps/chrome-host/start-host-chrome.sh +267 -0
- package/scripts/write-lockfile-hash.sh +21 -0
- package/setup.sh +107 -0
- package/src/components/Button/Button.jsx +4 -0
- package/src/components/Button/Button.module.scss +11 -0
- package/src/components/FileInputField/FileInputField.jsx +9 -2
- package/src/components/FormLayout/FormLayoutCustomField.jsx +4 -1
- package/src/components/FormLayout/FormLayoutCustomFieldContext.js +3 -0
- package/src/components/FormLayout/README.md +168 -161
- package/src/components/FormLayout/index.js +1 -0
- package/src/components/Popover/Popover.jsx +1 -0
- package/src/components/Popover/Popover.module.scss +1 -0
- package/src/components/Popover/README.md +29 -0
- package/src/components/Popover/_helpers/cleanPlacementStyle.js +1 -0
- package/src/components/Popover/_theme.scss +1 -0
- package/src/components/SelectField/SelectField.jsx +8 -3
- package/src/components/TextArea/TextArea.jsx +9 -2
- package/src/components/TextField/TextField.jsx +8 -3
- package/src/theme.scss +1 -0
- package/.env.playwright +0 -9
- package/.env.playwright.dist +0 -9
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
# Run on the HOST (macOS or Linux). Launches a dedicated, isolated Chrome with
|
|
4
|
+
# the DevTools (CDP) endpoint enabled so a containerized assistant can drive it.
|
|
5
|
+
#
|
|
6
|
+
# It uses its own dedicated --user-data-dir, so your everyday Chrome and logins
|
|
7
|
+
# are untouched. A separate profile is also required: Chrome only opens a debug
|
|
8
|
+
# port for a fresh instance, not for an already-running default profile.
|
|
9
|
+
#
|
|
10
|
+
# That profile is persistent (reused across runs, kept under $HOME) -- not
|
|
11
|
+
# ephemeral or sandboxed. Anything you sign in to here stays on disk and is
|
|
12
|
+
# reachable over the unauthenticated CDP port, so avoid logging in to sensitive
|
|
13
|
+
# accounts in this browser.
|
|
14
|
+
#
|
|
15
|
+
# Overrides (shell wins over the repo's .env); see README -> Platform support
|
|
16
|
+
# for the bind/platform details:
|
|
17
|
+
# CHROME_DEBUG_PORT CDP port (default 9333)
|
|
18
|
+
# CHROME_BIN explicit browser binary (else auto-detected)
|
|
19
|
+
# CHROME_DEBUG_BIND bind address (else auto-detected: loopback on Docker
|
|
20
|
+
# Desktop, docker bridge gateway on native Engine).
|
|
21
|
+
# SECURITY: a non-loopback bind exposes the port -- firewall it.
|
|
22
|
+
#
|
|
23
|
+
# Profile is always ~/.chrome-debug-profile-<COMPOSE_PROJECT_NAME> (not configurable).
|
|
24
|
+
|
|
25
|
+
set -eu
|
|
26
|
+
|
|
27
|
+
# Opens a real browser window, so it must run on the HOST, not in a container
|
|
28
|
+
# (/.dockerenv exists only inside one).
|
|
29
|
+
if [ -f /.dockerenv ]; then
|
|
30
|
+
echo "chrome-host: error: run start-host-chrome.sh on your HOST, not in a container." >&2
|
|
31
|
+
echo "chrome-host: it launches a Chrome window on your desktop for the containerized" >&2
|
|
32
|
+
echo "chrome-host: assistant to drive. Open a host terminal and run it there." >&2
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Fall back to the repo's .env (the file Docker Compose reads) so this launcher
|
|
37
|
+
# and the in-container proxy share one source of truth. Precedence: shell > .env
|
|
38
|
+
# > the defaults below.
|
|
39
|
+
env_root="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
|
40
|
+
while [ "$env_root" != "/" ] && [ ! -f "$env_root/docker-compose.yml" ]; do
|
|
41
|
+
env_root="$(dirname "$env_root")"
|
|
42
|
+
done
|
|
43
|
+
ENV_FILE="$env_root/.env"
|
|
44
|
+
# For each host knob, keep a value already set in the shell; otherwise eval the
|
|
45
|
+
# matching .env line. Letting the shell run the assignment strips quotes and
|
|
46
|
+
# inline comments for free. Values containing spaces must be quoted in .env.
|
|
47
|
+
if [ -f "$ENV_FILE" ]; then
|
|
48
|
+
for env_key in CHROME_DEBUG_PORT CHROME_BIN CHROME_DEBUG_BIND COMPOSE_PROJECT_NAME COMPOSE_DOCS_SERVER_PORT; do
|
|
49
|
+
eval "[ -n \"\${$env_key+x}\" ]" && continue
|
|
50
|
+
eval "$(grep -E "^[[:space:]]*$env_key=" "$ENV_FILE" | tail -n 1 || true)"
|
|
51
|
+
done
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
PORT="${CHROME_DEBUG_PORT:-9333}"
|
|
55
|
+
|
|
56
|
+
# Preflight: curl drives every CDP readiness probe below, on every platform.
|
|
57
|
+
if ! command -v curl >/dev/null 2>&1; then
|
|
58
|
+
echo "chrome-host: error: 'curl' is required to probe Chrome's CDP endpoint but is not installed." >&2
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Bind address. Explicit CHROME_DEBUG_BIND wins; otherwise auto-detect: loopback
|
|
63
|
+
# on Docker Desktop (incl. macOS), else the docker bridge gateway for native
|
|
64
|
+
# Engine. Binding to the gateway (not 0.0.0.0) keeps the port off your wider
|
|
65
|
+
# network. See README -> Platform support.
|
|
66
|
+
detect_bind() {
|
|
67
|
+
if [ "$(uname -s)" = "Darwin" ]; then
|
|
68
|
+
printf '127.0.0.1\n'
|
|
69
|
+
return 0
|
|
70
|
+
fi
|
|
71
|
+
case "$(docker info --format '{{.OperatingSystem}}' 2>/dev/null || true)" in
|
|
72
|
+
*"Docker Desktop"*)
|
|
73
|
+
printf '127.0.0.1\n'
|
|
74
|
+
return 0
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
# println each gateway on its own line, then take the first IPv4 -- an
|
|
78
|
+
# IPv6-enabled bridge would otherwise concatenate the v4 and v6 gateways into
|
|
79
|
+
# one malformed token that ncat cannot bind.
|
|
80
|
+
gateway_ip="$(docker network inspect bridge --format '{{range .IPAM.Config}}{{println .Gateway}}{{end}}' 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || true)"
|
|
81
|
+
if [ -n "$gateway_ip" ]; then
|
|
82
|
+
printf '%s\n' "$gateway_ip"
|
|
83
|
+
return 0
|
|
84
|
+
fi
|
|
85
|
+
return 1
|
|
86
|
+
}
|
|
87
|
+
# Preflight: auto-detecting the bind address shells out to the docker CLI. Skip
|
|
88
|
+
# the check when the bind is supplied explicitly, or on macOS (always loopback).
|
|
89
|
+
if [ -z "${CHROME_DEBUG_BIND:-}" ] && [ "$(uname -s)" != "Darwin" ] && ! command -v docker >/dev/null 2>&1; then
|
|
90
|
+
echo "chrome-host: error: auto-detecting the CDP bind address needs the 'docker' CLI, but it is" >&2
|
|
91
|
+
echo "chrome-host: not installed. Install Docker, or set CHROME_DEBUG_BIND (e.g. 127.0.0.1 for" >&2
|
|
92
|
+
echo "chrome-host: Docker Desktop) to skip detection." >&2
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
if [ -n "${CHROME_DEBUG_BIND:-}" ]; then
|
|
96
|
+
BIND="$CHROME_DEBUG_BIND"
|
|
97
|
+
else
|
|
98
|
+
BIND="$(detect_bind)" || true
|
|
99
|
+
if [ -z "$BIND" ]; then
|
|
100
|
+
echo "chrome-host: error: could not determine the Docker bridge gateway for the CDP forwarder" >&2
|
|
101
|
+
echo "chrome-host: (is the Docker daemon running?). Set CHROME_DEBUG_BIND to your docker bridge" >&2
|
|
102
|
+
echo "chrome-host: gateway IP to override, and retry." >&2
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
fi
|
|
106
|
+
case "$BIND" in
|
|
107
|
+
127.0.0.1 | ::1) ;;
|
|
108
|
+
*)
|
|
109
|
+
echo "chrome-host: warning: native Docker detected — exposing the CDP port on $BIND so the" >&2
|
|
110
|
+
echo "chrome-host: container can reach it. This exposes browser control beyond" >&2
|
|
111
|
+
echo "chrome-host: loopback; firewall the port. Native Docker also needs" >&2
|
|
112
|
+
echo "chrome-host: 'host.docker.internal:host-gateway' in the node service's" >&2
|
|
113
|
+
echo "chrome-host: extra_hosts. Set CHROME_DEBUG_BIND to override." >&2
|
|
114
|
+
;;
|
|
115
|
+
esac
|
|
116
|
+
|
|
117
|
+
# Preflight: a concrete non-loopback bind needs an ncat forwarder (see
|
|
118
|
+
# ensure_forwarder). Check ncat now, before launching Chrome, so a missing tool
|
|
119
|
+
# fails fast instead of orphaning a browser window. Skip it if a forwarder from
|
|
120
|
+
# a previous run is already serving the bind.
|
|
121
|
+
case "$BIND" in
|
|
122
|
+
127.0.0.1 | ::1 | 0.0.0.0 | ::) ;;
|
|
123
|
+
*)
|
|
124
|
+
if ! curl -s -m 2 "http://${BIND}:${PORT}/json/version" >/dev/null 2>&1 \
|
|
125
|
+
&& ! command -v ncat >/dev/null 2>&1; then
|
|
126
|
+
echo "chrome-host: error: this run must expose Chrome's CDP port ${PORT} on ${BIND} via an" >&2
|
|
127
|
+
echo "chrome-host: ncat forwarder, but 'ncat' is not installed. Install ncat (the 'nmap-ncat'" >&2
|
|
128
|
+
echo "chrome-host: or 'nmap' package, depending on your distro)." >&2
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
;;
|
|
132
|
+
esac
|
|
133
|
+
|
|
134
|
+
# Profile is always per-project and not configurable. COMPOSE_PROJECT_NAME comes
|
|
135
|
+
# from .env (or your shell); fall back to the repo directory name, like Compose.
|
|
136
|
+
PROJECT="${COMPOSE_PROJECT_NAME:-$(basename "$env_root")}"
|
|
137
|
+
PROFILE="$HOME/.chrome-debug-profile-$PROJECT"
|
|
138
|
+
|
|
139
|
+
find_chrome() {
|
|
140
|
+
if [ -n "${CHROME_BIN:-}" ]; then
|
|
141
|
+
printf '%s\n' "$CHROME_BIN"
|
|
142
|
+
return 0
|
|
143
|
+
fi
|
|
144
|
+
case "$(uname -s)" in
|
|
145
|
+
Darwin)
|
|
146
|
+
for candidate in \
|
|
147
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
|
|
148
|
+
"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta" \
|
|
149
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium" \
|
|
150
|
+
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"; do
|
|
151
|
+
if [ -x "$candidate" ]; then
|
|
152
|
+
printf '%s\n' "$candidate"
|
|
153
|
+
return 0
|
|
154
|
+
fi
|
|
155
|
+
done
|
|
156
|
+
;;
|
|
157
|
+
*)
|
|
158
|
+
for candidate in google-chrome google-chrome-stable chromium chromium-browser microsoft-edge brave-browser; do
|
|
159
|
+
resolved="$(command -v "$candidate" 2>/dev/null || true)"
|
|
160
|
+
if [ -n "$resolved" ]; then
|
|
161
|
+
printf '%s\n' "$resolved"
|
|
162
|
+
return 0
|
|
163
|
+
fi
|
|
164
|
+
done
|
|
165
|
+
;;
|
|
166
|
+
esac
|
|
167
|
+
return 1
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
# Headed Chromium pins DevTools to 127.0.0.1 and silently ignores
|
|
171
|
+
# --remote-debugging-address (Fedora's build, among others), so the launcher no
|
|
172
|
+
# longer passes that flag: Chrome always binds loopback, and ensure_forwarder
|
|
173
|
+
# spawns an ncat hop on $BIND:$PORT to expose it for the container. Loopback and
|
|
174
|
+
# wildcard binds need no hop -- loopback is already reachable, and a wildcard
|
|
175
|
+
# would collide with Chrome's own loopback port.
|
|
176
|
+
ensure_forwarder() {
|
|
177
|
+
bind=$1
|
|
178
|
+
port=$2
|
|
179
|
+
pidfile=$3
|
|
180
|
+
|
|
181
|
+
case "$bind" in 127.0.0.1 | ::1 | 0.0.0.0 | ::) return 0 ;; esac
|
|
182
|
+
|
|
183
|
+
mkdir -p "$(dirname "$pidfile")"
|
|
184
|
+
|
|
185
|
+
# A reachable bind:port means a forwarder from a previous run still serves it
|
|
186
|
+
# (Chrome itself only binds loopback), so reuse it.
|
|
187
|
+
if curl -s -m 2 "http://${bind}:${port}/json/version" >/dev/null 2>&1; then
|
|
188
|
+
echo "chrome-host: forwarder already serving ${bind}:${port}"
|
|
189
|
+
return 0
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
if ! command -v ncat >/dev/null 2>&1; then
|
|
193
|
+
echo "chrome-host: error: Chrome bound CDP to loopback only and 'ncat' is not installed." >&2
|
|
194
|
+
echo "chrome-host: install ncat (the 'nmap-ncat' or 'nmap' package, depending on your distro)" >&2
|
|
195
|
+
echo "chrome-host: so a host-side forwarder can expose ${port} on ${bind} for the container." >&2
|
|
196
|
+
return 1
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
if [ -f "$pidfile" ]; then
|
|
200
|
+
kill "$(cat "$pidfile")" 2>/dev/null || true
|
|
201
|
+
rm -f "$pidfile"
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
log=${pidfile%.pid}.log
|
|
205
|
+
nohup ncat -k -l "$bind" "$port" --sh-exec "ncat 127.0.0.1 $port" >"$log" 2>&1 &
|
|
206
|
+
echo $! >"$pidfile"
|
|
207
|
+
|
|
208
|
+
j=0
|
|
209
|
+
while [ "$j" -lt 20 ]; do
|
|
210
|
+
if curl -s -m 2 "http://${bind}:${port}/json/version" >/dev/null 2>&1; then
|
|
211
|
+
echo "chrome-host: forwarder ${bind}:${port} -> 127.0.0.1:${port} (pid $(cat "$pidfile"))"
|
|
212
|
+
return 0
|
|
213
|
+
fi
|
|
214
|
+
j=$((j + 1))
|
|
215
|
+
sleep 0.5
|
|
216
|
+
done
|
|
217
|
+
|
|
218
|
+
echo "chrome-host: error: forwarder failed to bind ${bind}:${port}; see $log" >&2
|
|
219
|
+
return 1
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if curl -s -m 2 "http://127.0.0.1:${PORT}/json/version" >/dev/null 2>&1; then
|
|
223
|
+
echo "chrome-host: debug Chrome already running on 127.0.0.1:${PORT}"
|
|
224
|
+
ensure_forwarder "$BIND" "$PORT" "$PROFILE/forwarder.pid" || exit 1
|
|
225
|
+
exit 0
|
|
226
|
+
fi
|
|
227
|
+
|
|
228
|
+
CHROME="$(find_chrome || true)"
|
|
229
|
+
if [ -z "${CHROME:-}" ]; then
|
|
230
|
+
echo "chrome-host: error: no Chrome/Chromium found. Set CHROME_BIN=/path/to/browser and retry." >&2
|
|
231
|
+
exit 1
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
mkdir -p "$PROFILE"
|
|
235
|
+
|
|
236
|
+
# Build the argument list (quote the glob so the shell doesn't expand '*').
|
|
237
|
+
# --ignore-certificate-errors skips the "Your connection is not private"
|
|
238
|
+
# interstitial for local HTTPS dev servers with a self-signed/absent cert.
|
|
239
|
+
# Acceptable here: this is a dedicated, isolated debug profile, not your
|
|
240
|
+
# everyday browser.
|
|
241
|
+
set -- \
|
|
242
|
+
--remote-debugging-port="$PORT" \
|
|
243
|
+
'--remote-allow-origins=*' \
|
|
244
|
+
--user-data-dir="$PROFILE" \
|
|
245
|
+
--no-first-run \
|
|
246
|
+
--no-default-browser-check \
|
|
247
|
+
--ignore-certificate-errors
|
|
248
|
+
set -- "$@" --new-window "http://localhost:${COMPOSE_DOCS_SERVER_PORT:-8000}"
|
|
249
|
+
|
|
250
|
+
nohup "$CHROME" "$@" >"$PROFILE/chrome-debug.log" 2>&1 &
|
|
251
|
+
|
|
252
|
+
i=0
|
|
253
|
+
while [ "$i" -lt 30 ]; do
|
|
254
|
+
if curl -s -m 2 "http://127.0.0.1:${PORT}/json/version" >/dev/null 2>&1; then
|
|
255
|
+
echo "chrome-host: debug Chrome ready on 127.0.0.1:${PORT}"
|
|
256
|
+
echo "chrome-host: binary: $CHROME"
|
|
257
|
+
echo "chrome-host: profile: $PROFILE"
|
|
258
|
+
echo "chrome-host: log: $PROFILE/chrome-debug.log"
|
|
259
|
+
ensure_forwarder "$BIND" "$PORT" "$PROFILE/forwarder.pid" || exit 1
|
|
260
|
+
exit 0
|
|
261
|
+
fi
|
|
262
|
+
i=$((i + 1))
|
|
263
|
+
sleep 0.5
|
|
264
|
+
done
|
|
265
|
+
|
|
266
|
+
echo "chrome-host: error: Chrome did not expose CDP on 127.0.0.1:${PORT}; see $PROFILE/chrome-debug.log" >&2
|
|
267
|
+
exit 1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# File to store the hash of the package-lock.json
|
|
6
|
+
LOCK_HASH_FILE="node_modules/.package-lock-hash"
|
|
7
|
+
|
|
8
|
+
# Parent directory of the script
|
|
9
|
+
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
|
|
10
|
+
|
|
11
|
+
# Change to the parent directory of the script
|
|
12
|
+
cd "$SCRIPT_DIR/.."
|
|
13
|
+
|
|
14
|
+
# Skip when running as an installed dependency,
|
|
15
|
+
# the published package contains no package-lock.json.
|
|
16
|
+
if [ ! -f package-lock.json ]; then
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# Record the hash of the lockfile we just installed against
|
|
21
|
+
sha256sum package-lock.json | awk '{print $1}' > "$LOCK_HASH_FILE"
|
package/setup.sh
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
DEFAULT_PROJECT_NAME="react-ui"
|
|
4
|
+
DEFAULT_USER_ID=1000
|
|
5
|
+
DEFAULT_GROUP_ID=1000
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
trap 'echo "Failed to set up project"; rm -f .env.temp; exit 1' ERR
|
|
9
|
+
|
|
10
|
+
# Function to handle sed command with cross-platform compatibility
|
|
11
|
+
sed_cmd() {
|
|
12
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
13
|
+
sed -i '' "$@"
|
|
14
|
+
else
|
|
15
|
+
sed -i "$@"
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
cd "$(dirname "$0")"
|
|
20
|
+
|
|
21
|
+
echo "Setting up project..."
|
|
22
|
+
|
|
23
|
+
# Create and configure .env file if it doesn't exist
|
|
24
|
+
if [ ! -f .env ]; then
|
|
25
|
+
echo "Creating .env file..."
|
|
26
|
+
cp .env.dist .env.temp
|
|
27
|
+
|
|
28
|
+
echo "Configuring .env file..."
|
|
29
|
+
|
|
30
|
+
PROJECT_PATH=$(pwd)
|
|
31
|
+
PROJECT_NAME=$(basename "$PROJECT_PATH")
|
|
32
|
+
|
|
33
|
+
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
34
|
+
# MacOS
|
|
35
|
+
USER_ID=$DEFAULT_USER_ID
|
|
36
|
+
GROUP_ID=$DEFAULT_GROUP_ID
|
|
37
|
+
else
|
|
38
|
+
# Linux
|
|
39
|
+
USER_ID=$(id -u)
|
|
40
|
+
GROUP_ID=$(id -g)
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
sed_cmd "s|^COMPOSE_PROJECT_NAME=.*|COMPOSE_PROJECT_NAME=$PROJECT_NAME|" .env.temp
|
|
44
|
+
sed_cmd "s|^COMPOSE_UID=.*|COMPOSE_UID=$USER_ID|" .env.temp
|
|
45
|
+
sed_cmd "s|^COMPOSE_GID=.*|COMPOSE_GID=$GROUP_ID|" .env.temp
|
|
46
|
+
|
|
47
|
+
LOCAL_SHELL=
|
|
48
|
+
if [ -n "$SHELL" ]; then
|
|
49
|
+
sed_cmd "s|^SHELL=.*|SHELL=$SHELL|" .env.temp
|
|
50
|
+
LOCAL_SHELL=$SHELL
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
LOCAL_EDITOR=
|
|
54
|
+
if [ -n "$EDITOR" ]; then
|
|
55
|
+
sed_cmd "s|^EDITOR=.*|EDITOR=$EDITOR|" .env.temp
|
|
56
|
+
LOCAL_EDITOR=$EDITOR
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
LOCAL_VISUAL=
|
|
60
|
+
if [ -n "$VISUAL" ]; then
|
|
61
|
+
sed_cmd "s|^VISUAL=.*|VISUAL=$VISUAL|" .env.temp
|
|
62
|
+
LOCAL_VISUAL=$VISUAL
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
cp .env.temp .env
|
|
66
|
+
rm .env.temp
|
|
67
|
+
|
|
68
|
+
echo "Configured .env file with the following values:"
|
|
69
|
+
echo "Project name: $PROJECT_NAME"
|
|
70
|
+
echo "Project path: $PROJECT_PATH"
|
|
71
|
+
echo "User ID: $USER_ID"
|
|
72
|
+
echo "Group ID: $GROUP_ID"
|
|
73
|
+
|
|
74
|
+
if [ -n "$LOCAL_SHELL" ]; then
|
|
75
|
+
echo "Shell: $LOCAL_SHELL"
|
|
76
|
+
fi
|
|
77
|
+
if [ -n "$LOCAL_EDITOR" ]; then
|
|
78
|
+
echo "Editor: $LOCAL_EDITOR"
|
|
79
|
+
fi
|
|
80
|
+
if [ -n "$LOCAL_VISUAL" ]; then
|
|
81
|
+
echo "Visual: $LOCAL_VISUAL"
|
|
82
|
+
fi
|
|
83
|
+
else
|
|
84
|
+
echo ".env file already exists, skipping creation."
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Create docker-compose.yml if it doesn't exist
|
|
88
|
+
if [ ! -f docker-compose.yml ]; then
|
|
89
|
+
echo "Creating and configuring docker-compose.yml file..."
|
|
90
|
+
cp docker-compose.yml.dist docker-compose.yml
|
|
91
|
+
|
|
92
|
+
DEFAULT_PROJECT_DEVCONTAINER_IMAGE="${DEFAULT_PROJECT_NAME}_devcontainer"
|
|
93
|
+
PROJECT_NAME=$(grep -E '^COMPOSE_PROJECT_NAME=' .env | cut -d '=' -f 2-)
|
|
94
|
+
PROJECT_DEVCONTAINER_IMAGE="${PROJECT_NAME}_devcontainer"
|
|
95
|
+
|
|
96
|
+
sed_cmd "s|image: $DEFAULT_PROJECT_DEVCONTAINER_IMAGE|image: $PROJECT_DEVCONTAINER_IMAGE|" docker-compose.yml
|
|
97
|
+
else
|
|
98
|
+
echo "docker-compose.yml file already exists, skipping creation."
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Configure the Chrome-host bridge networking (native Docker Engine only)
|
|
102
|
+
sh ./scripts/mcps/chrome-host/mcp-setup.sh
|
|
103
|
+
|
|
104
|
+
# Build Docker images
|
|
105
|
+
sh ./docker/build-docker-images.sh
|
|
106
|
+
|
|
107
|
+
echo "Project setup completed successfully!"
|
|
@@ -8,6 +8,7 @@ import { getRootPriorityClassName } from '../_helpers/getRootPriorityClassName';
|
|
|
8
8
|
import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
|
|
9
9
|
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
|
|
10
10
|
import { ButtonGroupContext } from '../ButtonGroup';
|
|
11
|
+
import { FormLayoutContext } from '../FormLayout';
|
|
11
12
|
import { InputGroupContext } from '../InputGroup/InputGroupContext';
|
|
12
13
|
import getRootLabelVisibilityClassName from './helpers/getRootLabelVisibilityClassName';
|
|
13
14
|
import styles from './Button.module.scss';
|
|
@@ -30,6 +31,7 @@ export const Button = React.forwardRef((props, ref) => {
|
|
|
30
31
|
...restProps
|
|
31
32
|
} = props;
|
|
32
33
|
const buttonGroupContext = useContext(ButtonGroupContext);
|
|
34
|
+
const formLayoutContext = useContext(FormLayoutContext);
|
|
33
35
|
const inputGroupContext = useContext(InputGroupContext);
|
|
34
36
|
|
|
35
37
|
if (buttonGroupContext && inputGroupContext) {
|
|
@@ -58,6 +60,8 @@ export const Button = React.forwardRef((props, ref) => {
|
|
|
58
60
|
resolveContextOrProp(buttonGroupContext && buttonGroupContext.block, block) && styles.isRootBlock,
|
|
59
61
|
buttonGroupContext && styles.isRootInButtonGroup,
|
|
60
62
|
inputGroupContext && styles.isRootInInputGroup,
|
|
63
|
+
formLayoutContext && styles.isRootInFormLayout,
|
|
64
|
+
formLayoutContext && formLayoutContext.layout === 'horizontal' && styles.isRootLayoutHorizontal,
|
|
61
65
|
feedbackIcon && styles.hasRootFeedback,
|
|
62
66
|
)}
|
|
63
67
|
disabled={resolveContextOrProp(primaryContext && primaryContext.disabled, disabled) || !!feedbackIcon}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// borders.
|
|
3
3
|
|
|
4
4
|
@use "sass:map";
|
|
5
|
+
@use "../../styles/settings/forms";
|
|
5
6
|
@use "../../styles/tools/breakpoint";
|
|
6
7
|
@use "../../styles/tools/collections";
|
|
7
8
|
@use "settings";
|
|
@@ -78,6 +79,16 @@
|
|
|
78
79
|
color: transparent;
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
.isRootInFormLayout {
|
|
83
|
+
justify-self: start;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.isRootLayoutHorizontal {
|
|
87
|
+
@include breakpoint.up(forms.$horizontal-breakpoint) {
|
|
88
|
+
grid-column-start: 2;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
81
92
|
.isRootInButtonGroup,
|
|
82
93
|
.isRootInInputGroup {
|
|
83
94
|
z-index: map.get(settings.$group-z-indexes, button);
|
|
@@ -16,7 +16,10 @@ import { getRootValidationStateClassName } from '../_helpers/getRootValidationSt
|
|
|
16
16
|
import { resolveContextOrProp } from '../_helpers/resolveContextOrProp';
|
|
17
17
|
import { InputGroupContext } from '../InputGroup';
|
|
18
18
|
import { Text } from '../Text';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
FormLayoutContext,
|
|
21
|
+
FormLayoutCustomFieldContext,
|
|
22
|
+
} from '../FormLayout';
|
|
20
23
|
import styles from './FileInputField.module.scss';
|
|
21
24
|
|
|
22
25
|
/* istanbul ignore file */
|
|
@@ -40,6 +43,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
40
43
|
} = props;
|
|
41
44
|
|
|
42
45
|
const formLayoutContext = useContext(FormLayoutContext);
|
|
46
|
+
const formLayoutCustomFieldContext = useContext(FormLayoutCustomFieldContext);
|
|
43
47
|
const inputGroupContext = useContext(InputGroupContext);
|
|
44
48
|
const translations = useContext(TranslationsContext);
|
|
45
49
|
|
|
@@ -172,7 +176,7 @@ export const FileInputField = React.forwardRef((props, ref) => {
|
|
|
172
176
|
<label
|
|
173
177
|
className={classNames(
|
|
174
178
|
styles.label,
|
|
175
|
-
(!isLabelVisible || inputGroupContext) && styles.isLabelHidden,
|
|
179
|
+
(!isLabelVisible || inputGroupContext || formLayoutCustomFieldContext) && styles.isLabelHidden,
|
|
176
180
|
)}
|
|
177
181
|
htmlFor={id}
|
|
178
182
|
id={`${id}__labelText`}
|
|
@@ -286,6 +290,9 @@ FileInputField.propTypes = {
|
|
|
286
290
|
/**
|
|
287
291
|
* If `false`, the label will be visually hidden (but remains accessible by assistive
|
|
288
292
|
* technologies).
|
|
293
|
+
*
|
|
294
|
+
* Automatically set to `false` when the component is rendered within `FormLayoutCustomField`
|
|
295
|
+
* component.
|
|
289
296
|
*/
|
|
290
297
|
isLabelVisible: PropTypes.bool,
|
|
291
298
|
/**
|
|
@@ -7,6 +7,7 @@ import { getRootSizeClassName } from '../_helpers/getRootSizeClassName';
|
|
|
7
7
|
import { getRootValidationStateClassName } from '../_helpers/getRootValidationStateClassName';
|
|
8
8
|
import { isChildrenEmpty } from '../../helpers/isChildrenEmpty/isChildrenEmpty';
|
|
9
9
|
import { FormLayoutContext } from './FormLayoutContext';
|
|
10
|
+
import { FormLayoutCustomFieldContext } from './FormLayoutCustomFieldContext';
|
|
10
11
|
import styles from './FormLayoutCustomField.module.scss';
|
|
11
12
|
|
|
12
13
|
const renderLabel = (id, label, labelForId) => {
|
|
@@ -73,7 +74,9 @@ export const FormLayoutCustomField = ({
|
|
|
73
74
|
className={styles.field}
|
|
74
75
|
id={id && `${id}__field`}
|
|
75
76
|
>
|
|
76
|
-
|
|
77
|
+
<FormLayoutCustomFieldContext.Provider value>
|
|
78
|
+
{children}
|
|
79
|
+
</FormLayoutCustomFieldContext.Provider>
|
|
77
80
|
</div>
|
|
78
81
|
</div>
|
|
79
82
|
);
|