Кроссплатформенный и мобильный интерфейс · Новый ресурс

Дизайн-система gluestack UI.

Создайте контрольный список полевого набора с настоящими генераторами основных компонентов Button и Input из gluestack, явными семантическими цветами v5 и полным исходным кодом React Native Web. Изучите проверку данных, действия с клавиатуры, стабильную идентификацию элементов и локально вычисляемый прогресс сбора вещей.

Руководство OpenDesign8 глав33 справочные записиАвторское руководство по приложению
01

gluestack UI Предварительный просмотр интерфейса дизайн-системы

Добавьте уникальный элемент, отметьте его как собранный и проверьте вычисляемый прогресс.

Соберите полевой наборОткрыть полный пример
Фактическое поведение @gluestack-ui/core 5.0.15 через React Native Web 0.21.3. Макет полевого набора, иллюстрации и модель состояний — оригинальная работа OpenDesign. В этом браузерном примере напрямую используются создатели и явные стили; это не набор компонентов NativeWind/Uniwind, сгенерированный CLI, и пример не тестировался на iOS или Android. · Справочник по реализации
02

gluestack UI Справочник по дизайну дизайн-системы

В справочнике отдельно представлены документированные светлые цвета v5 и установленный создатель core API. Прямые создатели не применяют тему CLI автоматически. В предварительном просмотре перечисленные цвета явно сопоставлены с оригинальными стилями; также используется более заметная пользовательская обводка фокуса. Геометрия и иллюстрации — решения на уровне приложения.

Документированные роли цветов для светлой темы v5

Источник
Название / правилоЗначение / конфигурацияПрименение
background#ffffff Холст страницы.
foreground#0a0a0a Обычный читаемый текст.
card#ffffff Поверхность карточки.
popover#ffffff Поверхность наложения; в этом примере всплывающие элементы не используются.
popover-foreground#0a0a0a Текст на поверхности наложения.
muted#f5f5f5 Вспомогательные поверхности, в том числе оригинальная панель с иллюстрацией.
muted-foreground#737373 Второстепенные описания и сведения о состоянии.
destructive#e7000b Сообщение об ошибке ввода; оно также отображается текстом.
border#e5e5e5 Обводки карточек и разделители списка.
input#e5e5e5 Обычная граница поля.
ring#d4d4d4 Документированный цвет кольца фокуса по умолчанию; в этом примере используется более заметная оригинальная обводка фокуса #737373.
primary#171717 Поверхность основного действия и заливка индикатора прогресса.
primary-foreground#fafafa Текст на тёмной поверхности действия.
secondary#f5f5f5 Поверхность действия с меньшим акцентом.
secondary-foreground#171717 Текст на вспомогательных поверхностях.
accent#f7f7f7 Дополнительная роль акцентной поверхности.
accent-foreground#343434 Текст для акцентной роли.

Фабрика Button из core и состояния

Источник
Название / правилоЗначение / конфигурацияПрименение
createButton{ Root, Text, Group, Spinner, Icon }Передайте настоящие хост-компоненты: создатель добавляет поведение, но не полноценную тему.
Button.TextText hostСохраняет текст кнопки в контексте её состояния.
Button.GroupGroup hostСгенерированный подкомпонент для группировки кнопок; в этом макете не используется.
Button.SpinnerSpinner hostСгенерированный индикатор загрузки; не показывайте его для мгновенного локального действия.
Button.IconIcon hostСгенерированный подкомпонент значка; в предварительном просмотре используются явные текстовые действия.
Button isDisabledbooleanОтключает фактическое действие при нажатии, а не только меняет внешний вид.
Button data-focus-visibletrue / falseВ оригинальной CSS для обозначения клавиатурного фокуса используется видимая обводка.
Button data-activetrue / falseПередаёт состояние нажатия для стилизации.

Контекст Input из core и свойства хост-компонентов

Источник
Название / правилоЗначение / конфигурацияПрименение
createInput{ Root, Icon, Slot, Input }Создаёт контекст поля и связанные с ним слоты.
Input.InputTextInput hostКомпонент ввода текста, возвращаемый создателем.
isInvalidInput root booleanПередаёт полю состояние недопустимого контекста и aria-invalid.
isRequiredInput root booleanПередаёт состояние обязательного поля; приложение отдельно проверяет ввод после удаления пробелов по краям.
value / onChangeTextControlled TextInput propsХраните черновой текст в состоянии React.
onSubmitEditingTextInput callbackВ этом браузерном примере добавляет элемент при нажатии Enter.
maxLength60 in the original studyОграничение TextInput, выбранное для этого приложения; не значение по умолчанию в gluestack.
aria-labelItem name in the original studyЗадаёт имя поля наряду с видимой меткой.
03

gluestack UI Полное руководство по дизайн-системе

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

DESIGN-gluestack-ui.md

Подробные рекомендации, отправная точка для реализации и ссылки на источники.

Скачать руководство

gluestack UI Версии, создатели и сгенерированные компоненты дизайн-системы

Выберите фактический способ реализации

У gluestack несколько уровней. Стандартный процесс установки генерирует стилизованные компоненты в приложении. В этом примере вместо этого импортируются createButton и createInput из установленного пакета core и передаются хост-компоненты React Native Web. Это различие важно: одной установки core недостаточно, чтобы получить сгенерированные варианты кнопок или полноценную тему.

Из этого руководства OpenDesign

В работающем примере зафиксированы версии core 5.0.15 и utils 5.0.6. Адаптеры React Native Web — настоящие компоненты, а оболочка и логика состояний — оригинальные. При создании полноценного приложения Expo или Next.js руководствуйтесь документацией по установке; чтобы воспроизвести именно этот браузерный пример, используйте файлы целиком.

gluestack UI Семантические цвета и явная стилизация дизайн-системы

Сначала сопоставьте роли, затем выбирайте оформление

На странице белый фон, тёмное основное действие, приглушённые вспомогательные области и заметные границы. Значения скопированы из документированной светлой палитры v5, а затем явно назначены через React Native styles и обычные CSS. Они не применяются незаметно во время выполнения через провайдер.

Для недопустимого поля используются обводка цвета ошибки и понятное пояснение, а фокус возвращается на поле. Оригинальная обводка фокуса темнее документированного цвета кольца, поэтому в таблице стилей этот выбор обозначен отдельно и не выдаётся за токен библиотеки.

Выполняйте миграции осознанно

Не стоит бездумно смешивать старые примеры с числовыми названиями палитры и семантическую терминологию v5. Прежде чем заменять название токена, изучите установленную сгенерированную конфигурацию и руководство по обновлению. Пример с прямыми создателями позволяет продемонстрировать поведение, но не подтверждает завершение миграции всего приложения.

gluestack UI Композиция Button и действия с клавиатуры в дизайн-системе

Передайте создателю все хост-компоненты

createButton принимает Pressable, Text, View, ActivityIndicator и хост для значка. Он возвращает Button и подкомпоненты Text, Group, Spinner и Icon. В полном примере используется Button.Text, а не обычная строка в корневом pressable-компоненте.

Сборка — синхронный переход состояния, поэтому здесь нет искусственного индикатора загрузки или задержки сохранения. В метке доступности каждого действия указано название элемента. Видимое действие переключается между «Собрать элемент» и «Разобрать», чтобы следующее действие было понятно.

Проверьте поведение отрисованного интерфейса

  1. Перейдите клавишей Tab к действию «Собрать элемент» и нажмите Space.
  2. Убедитесь, что изменились и текст состояния сборки, и значение прогресса.
  3. Нажмите «Разобрать» и проверьте, что тот же элемент остаётся в списке.
  4. Проверьте обводку фокуса: наведение мыши само по себе не подтверждает поддержку клавиатуры.

gluestack UI Контекст Input и полная валидация в дизайн-системе

Проверяйте значение, которое будет сохранено

Поле ввода остаётся управляемым через value и onChangeText. При добавлении сначала удаляются пробелы по краям чернового текста и проверяется, что он не пуст; затем имена сравниваются без учёта регистра. Отклонённое значение остаётся в поле, чтобы пользователь мог его исправить.

Корневому компоненту передаются isInvalid и isRequired; реальному полю — метка, ссылка на описание и ref для возврата фокуса. Валидация относится к логике приложения: указание core input как обязательного не создаёт правило проверки повторяющихся имён.

Обрабатывайте все видимые состояния поля

  • Начальное состояние: поле пустое, отображается подсказка о длине.
  • Ошибка: пояснение отображается в сообщении alert, фокус возвращается на поле.
  • Редактирование: при изменении чернового текста устаревшее сообщение об ошибке скрывается.
  • Принято: появляется новая несобранная строка, поле очищается, а сообщение о состоянии подтверждает добавление.

gluestack UI Стабильная идентификация и вычисляемый прогресс в дизайн-системе

Храните элементы, вычисляйте сводку

У каждого элемента есть стабильный числовой id, название и флаг packed. Ссылка ref выдаёт новые id; отображаемое название не используется как ключ React. Переключение состояния выполняется по id, поэтому обновления интерфейса для разных элементов не затрагивают соседние строки случайно.

Числитель прогресса вычисляется по флагам packed, а знаменатель — по текущему списку. Добавление несобранного элемента может снизить процент, не отменяя сборку уже собранных элементов. Это ожидаемый результат увеличения списка, а не ошибка анимации.

Сделайте сброс явным локальным действием

Сброс восстанавливает три примера элементов, очищает черновик и сообщение об ошибке, сбрасывает следующий id и сообщает о результате. При перезагрузке также отображается исходное состояние с примерами. За этим предварительным просмотром нет сервера, синхронизации аккаунта или постоянного хранилища.

gluestack UI Адаптивный макет и оригинальные иллюстрации дизайн-системы

Разделяйте поведение хост-компонентов и геометрию страницы

В композиции для компьютера список находится рядом с панелью ввода. При ширине 700 пикселей макет становится одноколоночным. Строки переносятся при необходимости, а длинные названия элементов разбиваются в пределах доступной ширины: кнопка фиксированной ширины не должна сдвигать весь документ по горизонтали.

Блокнот и карандаш — оригинальные фигуры CSS, а не скопированные фирменные ресурсы gluestack. Радиус карточки 14 пикселей, промежуток между панелями 24 пикселя и масштаб заголовков — решения для этого примера. В справочной таблице они отделены от документированных ролей цветов.

gluestack UI Доступность в браузере и область поддержки платформ дизайн-системы

Тестируйте именно ту среду, которая представлена

Предварительный просмотр отображает React Native Web и проверен в браузере. Это не подтверждает работу в нативных приложениях для iOS или Android. Приложение Expo необходимо отдельно проверить на размер областей касания, объявления для программ чтения с экрана, поведение при открытии клавиатуры и платформенную навигацию.

Элемент прогресса содержит своё название, минимальное и максимальное значения, а также текущее значение. Живое сообщение сообщает о выполненных действиях, не перемещая читателя с контрольного списка. При отклонении формы черновик сохраняется, а фокус возвращается к полю. Эти обязанности возлагаются на приложение и дополняют базовое поведение платформы.

gluestack UI Полная сборка дизайн-системы и границы зависимостей

Воспроизведите этот пример без изменений

Сохраните все четыре файла из раздела «Примеры компонентов» в одну папку и установите указанные ниже версии пакетов. В сборке react-native перенаправляется на react-native-web, поскольку внутренний код ядра импортирует модуль под нативным именем. Исходный код напрямую импортирует веб-компоненты и не загружает среду выполнения Expo.

Для установки ограниченного набора пакетов используется устаревший режим разрешения peer-зависимостей, поскольку эта версия предназначена только для веба. Это не рекомендация для полноценного нативного приложения: библиотека целиком указывает peer-зависимости для нативных интеграций, SVG и безопасных областей экрана, которые не используются в этом наборе из двух создателей компонентов. При расширении набора компонентов добавьте нужные peer-зависимости.

Изменяйте по одному слою за раз

  1. Соберите файлы без изменений и проверьте добавление, отклонение дубликатов, упаковку и сброс.
  2. Измените исходную компоновку или содержимое приложения, не затрагивая подключение создателей компонентов.
  3. При переходе на компоненты NativeWind, созданные генератором, замените настройку стилей и провайдеров отдельным этапом интеграции.
  4. После этого изменения повторно проверьте поведение клавиатуры и реальные целевые платформы.

gluestack UI Примеры компонентов дизайн-системы

app.jsx — полный пример использования основных компонентов

Подключение создателей компонентов и полная модель состояния контрольного списка.

jsx
import React,{useState,useRef} from 'react';
import{createRoot}from'react-dom/client';
import{Pressable,Text,View,TextInput,ActivityIndicator}from'react-native-web';
import{createButton}from'@gluestack-ui/core/button/creator';
import{createInput}from'@gluestack-ui/core/input/creator';
const Button=createButton({Root:Pressable,Text,Group:View,Spinner:ActivityIndicator,Icon:View});
const Input=createInput({Root:View,Input:TextInput,Slot:Pressable,Icon:View});
const seed=[{id:1,name:'Sketchbook',packed:true},{id:2,name:'Pencil roll',packed:false},{id:3,name:'Water bottle',packed:false}];
function App(){const[items,setItems]=useState(seed),[name,setName]=useState(''),[error,setError]=useState(''),[message,setMessage]=useState('Pack each item when it is ready.');const next=useRef(4),field=useRef(null);const count=items.filter(x=>x.packed).length;
function add(){const v=name.trim();if(!v||items.some(x=>x.name.toLowerCase()===v.toLowerCase())){setError(!v?'Enter the name of an item.':'That item is already in the kit.');field.current.focus();return}setItems([...items,{id:next.current++,name:v,packed:false}]);setName('');setError('');setMessage(v+' added to this local kit.')}
return <main><header><p className="eyebrow">GLUESTACK UI / CORE COMPONENT STUDY</p><h1>A small kit.<br/>A clearer start.</h1><p className="intro">Prepare a drawing kit with actual gluestack core Button and Input creators. Your checklist stays in this browser session.</p></header><div className="layout"><section className="panel"><div className="sectionhead"><h2>Your field kit</h2><span className="badge">{count} of {items.length} packed</span></div><div className="meter" role="progressbar" aria-label="Packed items" aria-valuemin={0} aria-valuemax={items.length} aria-valuenow={count}><i style={{width:100*count/items.length+'%'}}/></div><ul>{items.map(item=><li key={item.id}><div><strong>{item.name}</strong><span>{item.packed?'Packed and ready':'Still to pack'}</span></div><Button onPress={()=>{setItems(items.map(x=>x.id===item.id?{...x,packed:!x.packed}:x));setMessage(item.name+(item.packed?' marked to pack.':' marked packed.'))}} style={item.packed?styles.secondary:styles.primary} aria-label={(item.packed?'Unpack ':'Pack ')+item.name}><Button.Text style={{color:item.packed?'#171717':'#fafafa',fontSize:14,fontWeight:600}}>{item.packed?'Unpack':'Pack item'}</Button.Text></Button></li>)}</ul><p className="status" role="status">{message}</p></section><aside className="panel"><div className="drawing" aria-hidden="true"><span className="book">FIELD<br/>NOTES</span><i className="pencil"/></div><h2>Add one useful thing</h2><label htmlFor="kit-name">Item name</label><Input isInvalid={!!error} isRequired style={styles.input}><Input.Input id="kit-name" aria-label="Item name" aria-describedby={error?'kit-error':'kit-hint'} ref={field} value={name} onChangeText={v=>{setName(v);setError('')}} onSubmitEditing={add} maxLength={60} style={styles.field}/></Input><p id="kit-hint" className="hint">Use a short, unique name. Maximum 60 characters.</p>{error&&<p id="kit-error" className="error" role="alert">{error}</p>}<Button onPress={add} style={styles.primary}><Button.Text style={styles.primaryText}>Add to kit</Button.Text></Button><Button onPress={()=>{setItems(seed);setName('');setError('');setMessage('Example kit restored.');next.current=4}} style={styles.reset}><Button.Text style={{color:'#737373',fontSize:14}}>Reset example kit</Button.Text></Button></aside></div><p className="scope">Native @gluestack-ui/core 5.0.15 behavior rendered through React Native Web. Original OpenDesign layout and artwork; explicitly styled with documented v5 light color roles. This is a web-only study, not an Expo build or the CLI-generated NativeWind component set.</p></main>}
const styles={primary:{backgroundColor:'#171717',paddingVertical:12,paddingHorizontal:16,borderRadius:8,alignItems:'center',justifyContent:'center'},secondary:{backgroundColor:'#f5f5f5',paddingVertical:12,paddingHorizontal:16,borderRadius:8,alignItems:'center',justifyContent:'center'},primaryText:{color:'#fafafa',fontSize:14,fontWeight:600},input:{borderWidth:1,borderColor:'#e5e5e5',borderRadius:8,marginTop:8},field:{padding:12,fontSize:16,color:'#0a0a0a',outlineStyle:'none'},reset:{paddingVertical:16,alignItems:'center'}};
createRoot(document.getElementById('app')).render(<App/>);

Справочник по коду

style.css — исходная компоновка и явные роли светлой темы

Полная адаптивная оболочка, иллюстрации, контуры состояний и оформление фокуса в браузере.

css
*{box-sizing:border-box}body{margin:0;background:#fff;color:#0a0a0a;font-family:Arial,sans-serif}main{max-width:1100px;margin:auto;padding:40px}.eyebrow{font-size:12px;letter-spacing:.12em;font-weight:700}.intro{max-width:62ch;color:#737373;line-height:1.6}h1{font-size:52px;line-height:1.03;letter-spacing:-.045em;margin:24px 0}h2{font-size:22px;margin:0 0 20px}.layout{display:grid;grid-template-columns:1.35fr 1fr;gap:24px;margin-top:32px}.panel{border:1px solid #e5e5e5;border-radius:14px;padding:24px;min-width:0}.sectionhead{display:flex;gap:12px;justify-content:space-between;align-items:baseline;flex-wrap:wrap}.badge{font-size:12px;background:#f5f5f5;padding:6px 10px;border-radius:20px}.meter{height:6px;border-radius:8px;background:#f5f5f5;margin:6px 0 24px;overflow:hidden}.meter i{display:block;height:100%;background:#171717}ul{list-style:none;padding:0;margin:0}li{display:flex;gap:16px;align-items:center;justify-content:space-between;padding:20px 0;border-bottom:1px solid #e5e5e5}li>div:first-child{min-width:0;flex:1}li strong{display:block;font-size:16px;overflow-wrap:anywhere}li span{display:block;font-size:13px;color:#737373;margin-top:8px}.status{font-size:14px;line-height:1.6;margin-top:24px}.hint,.scope{font-size:12px;line-height:1.6;color:#737373}.scope{margin-top:28px}.error{font-size:14px;color:#e7000b;line-height:1.5}label{font-size:14px}.drawing{height:130px;background:#f5f5f5;border-radius:8px;display:flex;align-items:center;justify-content:center;gap:24px;margin-bottom:24px}.book{display:block;background:#171717;color:#fafafa;border-left:5px solid #737373;width:80px;height:96px;padding:22px 12px;font-size:12px;line-height:1.6;transform:rotate(-8deg)}.pencil{height:90px;width:8px;background:#a3a3a3;transform:rotate(14deg)}[data-focus-visible=true]{outline:3px solid #737373;outline-offset:3px}[data-invalid=true]{border-color:#e7000b!important}input:focus-visible{outline:2px solid #737373!important;outline-offset:3px}@media(max-width:700px){main{padding:20px}h1{font-size:40px}.layout{grid-template-columns:1fr}.panel{padding:20px}li{gap:12px;flex-wrap:wrap}li>div:first-child{flex-basis:120px}}

Справочник по коду

build.mjs — полная конфигурация сборщика для веба

Псевдоним для нативного импорта необходим, несмотря на то, что app.jsx импортирует веб-компоненты напрямую из React Native Web.

javascript
import { build } from 'esbuild';
await build({entryPoints:['app.jsx'],bundle:true,minify:true,outfile:'app.js',alias:{'react-native':'react-native-web'},resolveExtensions:['.web.js','.js','.jsx','.ts','.tsx','.json'],loader:{'.js':'jsx'},define:{'process.env.NODE_ENV':'"production"'}});

Справочник по коду

index.html — полная точка входа в браузере

Храните этот файл рядом с style.css и сгенерированным app.js.

html
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>gluestack field kit</title><link rel="stylesheet" href="style.css"></head><body><div id="app"></div><script src="app.js"></script></body></html>

Справочник по коду

04

gluestack UI Настройка агента дизайн-системы

Отправная точка для реализации

Сначала сохраните все четыре файла целиком. Эта настройка рассчитана только на показанный веб-сценарий и не инициализирует NativeWind, Uniwind, Expo или сгенерированный реестр компонентов.

sh
npm init -y
npm install [email protected] [email protected] [email protected] @gluestack-ui/[email protected] @gluestack-ui/[email protected] [email protected] --legacy-peer-deps
node build.mjs
python3 -m http.server 8000
# Open http://localhost:8000/

Запрос для вашего проекта

Промпт для AI-агента
Реализуйте полный веб-пример набора для похода на gluestack core 5.0.15 с помощью createButton/createInput и веб-компонентов React Native Web. Сохраните стабильные идентификаторы, управляемый текст черновика, обрезку пробелов и проверку на дубликаты, возврат фокуса, вычисляемое число упакованных предметов, локальный сброс и явное сопоставление ролей светлой темы v5. Отделяйте исходные решения по компоновке от стандартных настроек библиотеки. Не заявляйте о проверке на мобильных устройствах и сохранении данных на сервере.
05

gluestack UI Источники и область применения дизайн-системы

Фактическое поведение @gluestack-ui/core 5.0.15 через React Native Web 0.21.3. Компоновка набора для похода, иллюстрации и модель состояния — оригинальная работа OpenDesign. В этом веб-примере с прямым использованием создателей компонентов заданы явные стили; это не набор компонентов NativeWind/Uniwind, сгенерированный CLI, и он не тестировался на iOS или Android.