1676046330
Radix Colors
A gorgeous, accessible color system An open-source color system for designing beautiful, accessible websites and apps. A dart library for Radix Colors
View the Flutter web demo
Add the Radix Colors package to pubspec.yaml
dependencies:
radix_colors: ^1.0.3
Import the package in your dart file
import 'package:radix_colors/radix_colors.dart';
Radix Colors provides 15 color scales, designed for white foreground text at step 9.
RadixColors.amber;
RadixColors.dark.amber;
RadixColorsDynamic(context).amber;
RadixColors.amber.step1;
RadixColors.amber.step2;
RadixColors.amber.step3;
RadixColors.amber.step4;
RadixColors.amber.step5;
RadixColors.amber.step6;
RadixColors.amber.step7;
RadixColors.amber.step8;
RadixColors.amber.step9;
RadixColors.amber.step10;
RadixColors.amber.step11;
RadixColors.amber.step12;
Step | Use case |
---|---|
1 | App background |
2 | Subtle background |
3 | UI element background |
4 | Hovered UI element background |
5 | Active Selected UI element background |
6 | Subtle borders and separators |
7 | UI element border and focus rings |
8 | Hovered UI element border |
9 | Solid backgrounds |
10 | Hovered solid backgrounds |
11 | Low-contrast text |
12 | High-contrast text |
1
and 2
are designed for app backgrounds and subtle component backgrounds. You can use them interchangeably, depending on the vibe you're going for.Appropriate applications include:
3
, 4
, and 5
are designed for UI component backgrounds.3
is for normal states.4
is for hover states.5
is for pressed or selected states.Even if your component has a transparent background in its default state, you should skip Step 3
and use Step 4
for its hover state.
For call-to-action components that you want to draw particular attention to, you can bump each color one step higher to steps 4
, 5
, and 6
.
For complex components where you need many subtle colors to communicate different meanings, you can get creative and do something like:
3
for hovered backgrounds.4
for selected / pressed backgrounds.5
for "unread" backgrounds.6
for hovered "unread" backgrounds.6
, 7
, and 8
are designed for borders.6
is designed for subtle borders on components which are not interactive. For example sidebars, headers, cards, alerts, and separators.7
is designed for borders on interactive components, but can also be used for focus rings.8
is designed for borders on interactive components in their hover state.9
and 10
are designed for solid backgrounds.Step 9
has the highest chroma of all steps in the scale. In other words, it's the purest step, the step mixed with the least amount of white or black. Because 9
is the purest step, it has a wide range of applications:
10
is designed for component hover states, where step 9
is the component's normal state background.Most step 9 colors are designed for white foreground text. RadixColors.sky
, RadixColors.mint
, RadixColors.lime
, RadixColors.yellow
, and RadixColors.amber
are designed for black foreground text and steps 9
and 10
.
11
and 12
are designed for text.11
is designed for low-contrast text.12
is designed for high-contrast text.A major part of this documentation was lifted from the Radix Colors website.
Reach me on Twitter @lesliearkorful
Run this command:
With Flutter:
$ flutter pub add radix_colors
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
radix_colors: ^1.0.3
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:radix_colors/radix_colors.dart';
// ignore_for_file: library_private_types_in_public_api
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:radix_colors/radix_colors.dart';
import 'package:url_launcher/url_launcher_string.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Brightness brightness = Brightness.light;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Radix Colors Demo',
theme: ThemeData(
brightness: brightness,
primarySwatch: Colors.blue,
),
home: Builder(builder: (context) {
return Scaffold(
backgroundColor: RadixColorsDynamic(context).gray.step1,
appBar: AppBar(
elevation: 0,
backgroundColor: RadixColorsDynamic(context).gray.step1,
foregroundColor: RadixColorsDynamic(context).gray.step12,
systemOverlayStyle: SystemUiOverlayStyle.dark,
title: const Text(
'Flutter Radix Colors',
style: TextStyle(fontSize: 16),
),
leading: IconButton(
onPressed: () {
setState(() {
if (brightness == Brightness.dark) {
brightness = Brightness.light;
} else {
brightness = Brightness.dark;
}
});
},
icon: Icon(
brightness == Brightness.dark
? Icons.sunny
: Icons.nightlight_outlined,
),
),
actions: [
TextButton(
onPressed: () {
launchUrlString("https://pub.dev/packages/radix_colors");
},
child: const Text("View on pub.dev"),
),
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 14),
child: Align(
alignment: Alignment.topCenter,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 840),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"A gorgeous, accessible color system",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 28,
letterSpacing: -1,
fontWeight: FontWeight.w600,
color: RadixColorsDynamic(context).gray.step12,
),
),
const SizedBox(height: 12),
Text(
"An open-source color system for designing beautiful, accessible websites and apps.",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w300,
color: RadixColorsDynamic(context).gray.step11,
),
),
const SizedBox(height: 40),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: () {
launchUrlString(
"https://pub.dev/documentation/radix_colors/latest/",
);
},
child: const Text("API Documentation"),
),
const SizedBox(width: 16),
OutlinedButton(
onPressed: () {
launchUrlString(
"https://www.radix-ui.com/colors",
);
},
child: const Text("Radix Documentation"),
),
],
),
],
),
const SizedBox(height: 80),
colorSteps(),
const SizedBox(height: 6),
...RadixColorsDynamic(context)
.primaries
.take(28)
.map((color) {
return colorBlock(
"${color.name?.substring(0, 1).toUpperCase()}${color.name?.substring(1, color.name?.length)}",
color);
}).toList(),
const SizedBox(height: 80),
Text(
"The Scale",
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.w600,
color: RadixColorsDynamic(context).gray.step12,
),
),
const SizedBox(height: 12),
Text(
"An overview of all 30 Radix Colors scales.\nWhite and black are excluded from this demo",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w300,
color: RadixColorsDynamic(context).gray.step10,
),
),
const SizedBox(height: 40),
Text(
"Colors",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: RadixColorsDynamic(context).gray.step12,
),
),
const SizedBox(height: 12),
Text(
"Radix Colors provides 15 color scales, designed for white foreground text at step 9."
"\nThe RadixColorsDynamic class returns the matching color scale for the current Theme.brightness",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w300,
color: RadixColorsDynamic(context).gray.step10,
),
),
const SizedBox(height: 60),
...colorMap().map((color) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
color.name,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 16),
colorSteps(),
colorBlock(color.name.toLowerCase(), color.primary),
colorBlock(
"${color.name.toLowerCase()}A", color.accent),
colorBlock(
"${color.name.toLowerCase()}Dark",
color.primaryDark,
),
colorBlock(
"${color.name.toLowerCase()}DarkA",
color.accentDark,
bg: color.primaryDark.step1,
),
const SizedBox(height: 56),
],
);
}),
],
),
),
),
),
);
}),
);
}
Widget colorBlock(String name, RadixColor color, {Color? bg}) {
return SizedBox(
height: 36,
child: Row(
children: [
Container(
width: 100,
alignment: Alignment.centerLeft,
child: Text(
name,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w300,
color: RadixColors.gray.step10,
),
),
),
colorBox(color.step1, bg),
colorBox(color.step2, bg),
colorBox(color.step3, bg),
colorBox(color.step4, bg),
colorBox(color.step5, bg),
colorBox(color.step6, bg),
colorBox(color.step7, bg),
colorBox(color.step8, bg),
colorBox(color.step9, bg),
colorBox(color.step10, bg),
colorBox(color.step11, bg),
colorBox(color.step12, bg),
],
),
);
}
Widget colorBox(Color color, Color? bg) {
return Expanded(
child: Container(
color: bg,
margin: const EdgeInsets.only(right: 2, bottom: 2),
child: Container(
color: color,
width: double.infinity,
height: double.infinity,
),
),
);
}
Widget colorSteps() {
return Row(
children: [
const SizedBox(width: 70),
...List.generate(12, (index) {
return Expanded(
child: Container(
alignment: Alignment.center,
padding: const EdgeInsets.only(bottom: 4),
child: Text(
"${index + 1}",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w300,
color: RadixColors.gray,
),
),
),
);
}),
],
);
}
}
List<_ColorsDemo> colorMap() {
return [
_ColorsDemo(
name: "Tomato",
primary: RadixColors.tomato,
accent: RadixColors.tomatoA,
primaryDark: RadixColors.dark.tomato,
accentDark: RadixColors.dark.tomatoA,
),
_ColorsDemo(
name: "Red",
primary: RadixColors.red,
accent: RadixColors.redA,
primaryDark: RadixColors.dark.red,
accentDark: RadixColors.dark.redA,
),
_ColorsDemo(
name: "Crimson",
primary: RadixColors.crimson,
accent: RadixColors.crimsonA,
primaryDark: RadixColors.dark.crimson,
accentDark: RadixColors.dark.crimsonA,
),
_ColorsDemo(
name: "Pink",
primary: RadixColors.pink,
accent: RadixColors.pinkA,
primaryDark: RadixColors.dark.pink,
accentDark: RadixColors.dark.pinkA,
),
_ColorsDemo(
name: "Plum",
primary: RadixColors.plum,
accent: RadixColors.plumA,
primaryDark: RadixColors.dark.plum,
accentDark: RadixColors.dark.plumA,
),
_ColorsDemo(
name: "Purple",
primary: RadixColors.purple,
accent: RadixColors.purpleA,
primaryDark: RadixColors.dark.purple,
accentDark: RadixColors.dark.purpleA,
),
_ColorsDemo(
name: "Violet",
primary: RadixColors.violet,
accent: RadixColors.violetA,
primaryDark: RadixColors.dark.violet,
accentDark: RadixColors.dark.violetA,
),
_ColorsDemo(
name: "Indigo",
primary: RadixColors.indigo,
accent: RadixColors.indigoA,
primaryDark: RadixColors.dark.indigo,
accentDark: RadixColors.dark.indigoA,
),
_ColorsDemo(
name: "Blue",
primary: RadixColors.blue,
accent: RadixColors.blueA,
primaryDark: RadixColors.dark.blue,
accentDark: RadixColors.dark.blueA,
),
_ColorsDemo(
name: "Cyan",
primary: RadixColors.cyan,
accent: RadixColors.cyanA,
primaryDark: RadixColors.dark.cyan,
accentDark: RadixColors.dark.cyanA,
),
_ColorsDemo(
name: "Teal",
primary: RadixColors.teal,
accent: RadixColors.tealA,
primaryDark: RadixColors.dark.teal,
accentDark: RadixColors.dark.tealA,
),
_ColorsDemo(
name: "Green",
primary: RadixColors.green,
accent: RadixColors.greenA,
primaryDark: RadixColors.dark.green,
accentDark: RadixColors.dark.greenA,
),
_ColorsDemo(
name: "Grass",
primary: RadixColors.grass,
accent: RadixColors.grassA,
primaryDark: RadixColors.dark.grass,
accentDark: RadixColors.dark.grassA,
),
_ColorsDemo(
name: "Orange",
primary: RadixColors.orange,
accent: RadixColors.orangeA,
primaryDark: RadixColors.dark.orange,
accentDark: RadixColors.dark.orangeA,
),
_ColorsDemo(
name: "Brown",
primary: RadixColors.brown,
accent: RadixColors.brownA,
primaryDark: RadixColors.dark.brown,
accentDark: RadixColors.dark.brownA,
),
_ColorsDemo(
name: "Sky",
primary: RadixColors.sky,
accent: RadixColors.skyA,
primaryDark: RadixColors.dark.sky,
accentDark: RadixColors.dark.skyA,
),
_ColorsDemo(
name: "Mint",
primary: RadixColors.mint,
accent: RadixColors.mintA,
primaryDark: RadixColors.dark.mint,
accentDark: RadixColors.dark.mintA,
),
_ColorsDemo(
name: "Lime",
primary: RadixColors.lime,
accent: RadixColors.limeA,
primaryDark: RadixColors.dark.lime,
accentDark: RadixColors.dark.limeA,
),
_ColorsDemo(
name: "Yellow",
primary: RadixColors.yellow,
accent: RadixColors.yellowA,
primaryDark: RadixColors.dark.yellow,
accentDark: RadixColors.dark.yellowA,
),
_ColorsDemo(
name: "Amber",
primary: RadixColors.amber,
accent: RadixColors.amberA,
primaryDark: RadixColors.dark.amber,
accentDark: RadixColors.dark.amberA,
),
_ColorsDemo(
name: "Gray",
primary: RadixColors.gray,
accent: RadixColors.grayA,
primaryDark: RadixColors.dark.gray,
accentDark: RadixColors.dark.grayA,
),
_ColorsDemo(
name: "Mauve",
primary: RadixColors.mauve,
accent: RadixColors.mauveA,
primaryDark: RadixColors.dark.mauve,
accentDark: RadixColors.dark.mauveA,
),
_ColorsDemo(
name: "Slate",
primary: RadixColors.slate,
accent: RadixColors.slateA,
primaryDark: RadixColors.dark.slate,
accentDark: RadixColors.dark.slateA,
),
_ColorsDemo(
name: "Sage",
primary: RadixColors.sage,
accent: RadixColors.sageA,
primaryDark: RadixColors.dark.sage,
accentDark: RadixColors.dark.sageA,
),
_ColorsDemo(
name: "Olive",
primary: RadixColors.olive,
accent: RadixColors.oliveA,
primaryDark: RadixColors.dark.olive,
accentDark: RadixColors.dark.oliveA,
),
_ColorsDemo(
name: "Sand",
primary: RadixColors.sand,
accent: RadixColors.sandA,
primaryDark: RadixColors.dark.sand,
accentDark: RadixColors.dark.sandA,
),
_ColorsDemo(
name: "Gold",
primary: RadixColors.gold,
accent: RadixColors.goldA,
primaryDark: RadixColors.dark.gold,
accentDark: RadixColors.dark.goldA,
),
_ColorsDemo(
name: "Bronze",
primary: RadixColors.bronze,
accent: RadixColors.bronzeA,
primaryDark: RadixColors.dark.bronze,
accentDark: RadixColors.dark.bronzeA,
),
];
}
class _ColorsDemo {
final String name;
final RadixColor primary;
final RadixColor accent;
final RadixColor primaryDark;
final RadixColor accentDark;
_ColorsDemo({
required this.name,
required this.primary,
required this.accent,
required this.primaryDark,
required this.accentDark,
});
}
Download Details:
Author: lesliearkorful
Source Code: https://github.com/lesliearkorful/radix_colors
1674786060
Beautifully designed components built with Radix UI and Tailwind CSS.
Warning This is work in progress. I'm building this in public. You can follow the progress on Twitter @shadcn.
Starting a new project? Check out the Next.js template.
npx create-next-app -e https://github.com/shadcn/next-template
@next/font
next-themes
@ianvs/prettier-plugin-sort-imports
tailwind-merge
tailwindcss-animate
clsx
class-variance-authority
eslint-plugin-tailwindcss
Author: Shadcn
Source Code: https://github.com/shadcn/ui
1673309940
Radix tree implementation for Crystal language
Add this to your application's shard.yml
:
dependencies:
radix:
github: luislavena/radix
You can associate a payload with each path added to the tree:
require "radix"
tree = Radix::Tree(Symbol).new
tree.add "/products", :products
tree.add "/products/featured", :featured
result = tree.find "/products/featured"
if result.found?
puts result.payload # => :featured
end
The types allowed for payload are defined on Tree definition:
tree = Radix::Tree(Symbol).new
# Good, since Symbol is allowed as payload
tree.add "/", :root
# Compilation error, Int32 is not allowed
tree.add "/meaning-of-life", 42
Can combine multiple types if needed:
tree = Radix::Tree(Int32 | String | Symbol).new
tree.add "/", :root
tree.add "/meaning-of-life", 42
tree.add "/hello", "world"
You can also extract values from placeholders (as named segments or globbing):
tree.add "/products/:id", :product
result = tree.find "/products/1234"
if result.found?
puts result.params["id"]? # => "1234"
end
Please see Radix::Tree#add
documentation for more usage examples.
Pretty much all Radix implementations have their limitations and this project is no exception.
When designing and adding paths to a Tree, please consider that two different named parameters cannot share the same level:
tree.add "/", :root
tree.add "/:post", :post
tree.add "/:category/:post", :category_post # => Radix::Tree::SharedKeyError
This is because different named parameters at the same level will result in incorrect params
when lookup is performed, and sometimes the value for post
or category
parameters will not be stored as expected.
To avoid this issue, usage of explicit keys that differentiate each path is recommended.
For example, following a good SEO practice will be consider /:post
as absolute permalink for the post and have a list of categories which links to the permalinks of the posts under that category:
tree.add "/", :root
tree.add "/:post", :post # this is post permalink
tree.add "/categories", :categories # list of categories
tree.add "/categories/:category", :category # listing of posts under each category
This project has been inspired and adapted from julienschmidt/httprouter and spriet2000/vertx-http-router Go and Java implementations, respectively.
Changes to logic and optimizations have been made to take advantage of Crystal's features.
git checkout -b my-new-feature
)git commit -am 'Add some feature'
)git push origin my-new-feature
)Author: luislavena
Source Code: https://github.com/luislavena/radix
License: MIT license
1669621194
Learn about Radix and use Radix Primitives to develop a basic React component library as a subset of a design system. This guide aims to provide you with a deeper understanding of Radix and how it can be used to build out design systems and component libraries.
Radix is an open source library that provides components for building accessible, high-quality React web applications and design systems. Radix is part of a new wave of headless components being created in the frontend space, and this pattern has been gaining a lot of traction lately.
This guide aims to provide you with a deeper understanding of Radix and how it can be used to build out design systems and component libraries. The latter half of this article provides an in-depth tutorial on building a sample component library with Radix Primitives.
Radix is composed of a suite of three products: Primitives, Colors, and Icons. These tools can be used to build out design systems. Let’s take a closer look at each individual product and how they can be used separately or collaboratively to suit your needs.
Radix Primitives is the library’s flagship product. It is described as a collection of “unstyled, accessible components for building high‑quality design systems and web apps in React.” Instead of reinventing the wheel, Radix Primitives handle a lot of the tricky parts when it comes to building out common component patterns.
Building out accessible widgets that meet the WAI-ARIA standards and properly handle aspects like keyboard navigation can be a large undertaking. Libraries like Radix aim to simplify this often difficult process for developers by providing a set of flexible and extensible components that are prebuilt with accessibility and developer experience in mind.
Radix Colors is a carefully crafted color system designed for building stunning web apps. It provides additional features like automatic dark mode compatibility which makes switching to a dark theme as simple as applying a class to a container, the ability to compose color palettes to work with your app’s brand or theme, and accessibility considerations that are guaranteed to pass WCAG contrast ratio requirements.
Radix Colors provides a set of scales that are JavaScript objects intended to integrate with your preferred styling solution, ranging from vanilla CSS to CSS-in-JS options (e.g., styled-components).
Radix Icons touts itself as a “crisp set of 15×15 icons designed by the WorkOS team.” All the icons are available as individual components that can be installed via a single package.
Simply import the respective icons, and you can add them to your apps like you would any other React component. Radix Icons are also available in other forms like downloadable SVGs, along with Figma and Sketch files.
I often see the terms design system and component library used interchangeably. Although these two concepts are related, they pertain to different parts of a larger whole.
In an effort to diffuse any confusion, I’ll define each term to point out the distinction and differences between the two related terminologies.
The Nielsen Norman Group, a renowned and trusted UX research and consulting firm, defines a design system as a “…set of standards to manage design at scale by reducing redundancy while creating a shared language and visual consistency across different pages and channels.”
A typical design system may consist of the following three items:
Some examples of popular design systems include Google’s Material Design, the Atlassian Design System, and Carbon Design System by IBM.
A component library consists of a collection of UI elements (i.e., components) that can be reused across an application. These components implement the design standards established throughout the style guide.
Due to their composability, components make it easier to implement wireframes provided by a design team. Common components found in a library range from buttons and individual form elements (e.g., inputs, checkboxes, etc.) to more complex elements like date pickers.
Some examples of popular component libraries include MUI (the artist formerly known as Material UI), Headless UI by Tailwind Labs, and of course Radix UI.
Because a design system is a large entity that often involves multiple stakeholders across varying fields, building one is quite an arduous feat. In an effort to keep this article digestible, we will build out a component library as a subset of a design system. However, it is important to note that Radix offers a full suite of tools that provide you with the resources to build out full-fledged design systems.
Documentation within a UI library is imperative because it provides a single location where developers and designers alike can view a list of the components within a design system. Developers can also leverage this documentation as a sandbox environment where they can test out components in multiple states and read up on the different properties that can be used to customize an individual component.
Because documentation is so important, our sample project has been preconfigured with React Styleguidist, a development environment for building React components. We’ll use this tool to document the components as we build them out.
To clone the radix-component-library project from GitHub, open your terminal and run the following command:
git clone https://github.com/Cool-Runningz/radix-component-library.git
Next, cd into the radix-component-library
folder:
cd radix-component-library
Install the project dependencies defined in the package.json
file:
npm install
Once the installation is completed, start the development server:
npm run library
Navigate to http://localhost:3020/ in your browser. You should see the following screen:
Now that we have the project up and running, we can begin to incorporate Radix into our component library.
The first component we will build is a range input that adheres to the WAI-ARIA slider design pattern.
Creating a custom range input that has a consistent appearance across browsers can be an arduous task. However, Radix makes this process simpler by providing a Slider Primitive. The range input is sometimes referred to as a slider; throughout the rest of this article, I will use these terms interchangeably.
In Radix, each Primitive can be installed individually so you can adopt them incrementally. Primitives are also versioned independently, to further facilitate incremental adoption. This leads to less bloat in your codebases, as you only need to import the individual components that you need.
To build a range input component, start by installing the Slider Primitive:
npm install @radix-ui/react-slider
Next, open the RangeInput.jsx
file, import the Radix Primitive, and add the boilerplate for the slider component. At this point, your file should include the following code:
import React from 'react'
import PropTypes from "prop-types"
import "./RangeInput.css"
import * as SliderPrimitive from '@radix-ui/react-slider';
const RangeInput = (props) => {
return (
<SliderPrimitive.Root className="rootSlider" value={props.value}>
<SliderPrimitive.Track className="trackSlider">
<SliderPrimitive.Range className="rangeSlider" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="thumbSlider" />
</SliderPrimitive.Root>
)
}
export default RangeInput
The anatomy of a Slider
component in Radix consists of the following four elements:
Slider.Range
Slider.Track
At this point, if you navigate to http://localhost:3020/#rangeinput you’ll notice that the UI is empty. This is because Radix components do not apply any styles by default.
Next, we’ll go through the process of adding CSS to the custom component.
Radix is not opinionated about how to style components and it is compatible with a variety of CSS solutions, providing you with complete control over styling.
Using plain ol’ CSS, we’ll style to RangeInput
component to match the one found in the “Estimate your cost – Professional” section of LogRocket’s Pricing page:
Root
The Root
contains all the parts of a slider and it will render an input
for each thumb.
Create a .rootSlider
class in RangeInput.css
and add the following code:
.rootSlider {
display: flex;
align-items: center;
position: relative;
height: 1.5rem;
max-width: 30rem;
}
Track
The Track
contains the Slider.Range
and is the part of the slider that the thumb runs along.
Create a .trackSlider
class in RangeInput.css
and add the following code:
.trackSlider {
background-color: #fafafa;
border: 1px solid #d3d3d3;
position: relative;
flex-grow: 1;
border-radius: 10px;
height: 1rem;
}
Range
The Range
must live inside Slider.Track
and represents the range of values that is selected.
Create a .rangeSlider
class in RangeInput.css
and add the following code:
.rangeSlider {
position: absolute;
background: linear-gradient(90deg,#252678,#764abc);
height: 100%;
border-radius: 10px;
}
Thumb
The Thumb
is the element on the track that the user can move around to select varying range values.
Create a .thumbSlider
class in RangeInput.css
and add the following code:
.thumbSlider {
display: block;
width: 20px;
height: 20px;
background-color: #764abc;
border-radius: 30px;
border: 1px solid #d9d9d9;
}
.thumbSlider:hover {
cursor: pointer;
}
.thumbSlider:focus {
outline: 1px solid white;
}
With all these styles applied, if you navigate back to http://localhost:3020/#rangeinput you should see the following being rendered:
The last step of building the RangeInput
component is to configure it to be able to accept props, which in turn will make it more reusable and customizable. For this example, we‘ll add three props:
label
: Applied as the aria-label value for the element with the slider
rolevalue
: Represents the controlled value of the slider and must be used in conjunction with onValueChange
onValueChange
: The event handler that gets called when the value changesRadix components can be controlled or uncontrolled. Adding the value
and onValueChange
props will turn the RangeInput
into a controlled component.
The markdown file that renders the RangeInput
in the sandbox environment has been preconfigured to pass in props. Now we need to update the component to be able to handle those props.
First, we need to add typechecking with PropTypes. The prop-types library has already been imported near the top of RangeInput.jsx
so now you can add the propTypes
definition at the bottom of the file, like so:
RangeInput.propTypes = {
/** Applied as the aria-label value of the element with the "slider" role */
label: PropTypes.string.isRequired,
/** The controlled value of the slider. */
value: PropTypes.arrayOf(PropTypes.number).isRequired,
/** Event handler called when the value changes. */
onValueChange: PropTypes.func.isRequired
}
When propTypes
are present, React Styleguidist will pick up the props from the object’s declarations and display them in a table. Now, anyone looking at this example will know the exact props that are needed to properly implement this component.
Next, we want to update the JSX within RangeInput.jsx
to be able to pass the props to the RangeInput
component. The value
and onValueChange
props need to get applied to the SliderPrimitive.Root
element, while the label
prop needs to get applied to the SliderPrimitive.Thumb
element.
With those updates, the RangeInput.jsx
file should now contain the following code:
import React from 'react'
import PropTypes from "prop-types"
import "./RangeInput.css"
import * as SliderPrimitive from '@radix-ui/react-slider';
const RangeInput = (props) => {
return (
<SliderPrimitive.Root className="rootSlider"
value={props.value} onValueChange={props.onValueChange}>
<SliderPrimitive.Track className="trackSlider">
<SliderPrimitive.Range className="rangeSlider" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="thumbSlider" aria-label={props.label}
/>
</SliderPrimitive.Root>
)
}
export default RangeInput
RangeInput.propTypes = {
/** Applied as the aria-label value of the element with the "slider" role */
label: PropTypes.string.isRequired,
/** The controlled value of the slider. */
value: PropTypes.arrayOf(PropTypes.number).isRequired,
/** Event handler called when the value changes. */
onValueChange: PropTypes.func.isRequired
}
Voila!
With minimal code, we were able to leverage the Radix Slider to create an accessible and functional RangeInput
component that is styled to match the LogRocket theme.
Next, we’ll demonstrate how to implement one more component for our UI library.
The second component we will build is a Tabs element that leverages the Radix Tabs Primitive. This component is constructed to adhere to the WAI-ARIA Tabs design pattern.
First, install the Tabs Primitive:
npm install @radix-ui/react-tabs
Next, open the Tabs.jsx
file, import the Radix Primitive, and add the boilerplate for the Tabs
component.
Your file should include the following code:
import React from 'react'
import PropTypes from "prop-types"
import "./Tabs.css"
import * as TabsPrimitive from "@radix-ui/react-tabs";
const Tabs = (props) => {
return (
<TabsPrimitive.Root>
<TabsPrimitive.List>
<TabsPrimitive.Trigger value="tab1">Tab 1</TabsPrimitive.Trigger>
<TabsPrimitive.Trigger value="tab2">Tab 2</TabsPrimitive.Trigger>
</TabsPrimitive.List>
<TabsPrimitive.Content value="tab1">
Content for Tab # 1
</TabsPrimitive.Content>
<TabsPrimitive.Content value="tab2">
Content for Tab # 2
</TabsPrimitive.Content>
</TabsPrimitive.Root>
)
}
export default Tabs
The anatomy of a Radix Tabs
component consists of the following four elements:
Tabs
component partsIf you navigate to http://localhost:3020/#tabs, the default version of the component should display like this:
Next, we need to configure the Tabs
component to be able to accept props. For this example, we’ll add three props:
tabsList
: Array of tabs to be displayedvalue
: Controlled value of the tab to activate; this should be used in conjunction with onValueChange
onValueChange
: Event handler called when the value changesCurrently, the Tabs
component only displays a fixed number of tabs with hardcoded values. In an effort to make the component more flexible so that it can render an arbitrary number of tabs, we will update the JSX in Tabs.jsx
with the following code:
import React from 'react'
import PropTypes from "prop-types"
import "./Tabs.css"
import * as TabsPrimitive from "@radix-ui/react-tabs";
const Tabs = (props) => {
return (
<TabsPrimitive.Root
className="rootTabs"
value={props.value}
onValueChange={props.onValueChange}
>
<TabsPrimitive.List className="listTabs">
{props.tabsList.map((tab) => {
return (
<TabsPrimitive.Trigger className="triggerTabs"
key={tab.id || `${index}-${tab.value}`}
value={tab.value}
>
{tab.label}
</TabsPrimitive.Trigger>);
})}
</TabsPrimitive.List>
{props.tabsList.map((tab) => {
return (
<TabsPrimitive.Content className="contentTabs"
key={tab.id || `${index}-${tab.value}`}
value={tab.value}
>
{tab.content}
</TabsPrimitive.Content>
);
})}
</TabsPrimitive.Root>
)
}
export default Tabs
Tabs.propTypes = {
tabsList: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string,
label: PropTypes.string.isRequired,
content: PropTypes.element.isRequired,
value: PropTypes.string.isRequired
})
),
/** The controlled value of the tab to activate. */
value: PropTypes.string.isRequired,
/** Event handler called when the value changes. */
onValueChange: PropTypes.func.isRequired
}
Tabs.md has been pre-configured to pass in an array of items to the tabsList
prop. When we navigate to http://localhost:3020/#tabs, we should see the following:
Similar to the previous component, we’ll use vanilla CSS to style the Tabs
component to match the one found in the “Estimate your cost” section of LogRocket’s Pricing page:
Root
The Root
contains all the elements that are contained within the tabs component.
Create a .rootTabs
class in Tabs.css
and add the following code:
.rootTabs {
background-color: white;
}
List
The List
contains all the Trigger
elements.
Create a .listTabs
class in Tabs.css
and add the following code:
.listTabs {
align-items: center;
display: flex;
justify-content: center;
margin: 0 auto;
width: 85%;
}
Trigger
The Trigger
is the button that controls displaying the selected tabs content.
Create a .triggerTabs
class in Tabs.css
and add the following code:
.triggerTabs {
color: #764abc;
font-family: "Avenir";
background: none;
border: none;
display: block;
cursor: pointer;
font-size: 20px;
font-weight: 500;
opacity: 0.5;
padding: 30px;
position: relative;
}
.triggerTabs[data-state="active"] {
opacity: 1;
}
.triggerTabs[data-state="active"]::after {
background-color: #764abc;
border-radius: 12px;
bottom: -4px;
content: "";
height: 6px;
left: 0;
position: absolute;
width: 100%;
}
Content
The Content
contains the content that is associated with each tab.
Create a .contentTabs
class in Tabs.css
and add the following CSS:
.contentTabs {
border-top: 3px solid hsla(0, 0%, 44%, 0.15);
padding: 30px 55px;
}
With all those styles applied, if you navigate back to http://localhost:3020/#tabs you should now see the following being rendered:
This completes the second example and shows how you can leverage the Radix Tabs Primitive to quickly build a functional and accessible Tabs
component that is styled to match the LogRocket theme.
In this article, we investigated Radix and discussed how you can use its suite of products to create design systems. Building incrementally, we used Radix Primitives to develop a basic React component library as a subset of a design system.
Developing custom components can be tricky, and incorporating features like accessibility and keyboard navigation can exponentially increase complexity, further validating the benefits of leveraging tools like Radix that aim to simplify this process.
The repository for the component library developed in this article can be found on my GitHub. In addition, you can view a deployed version of the final project here.
Thank you for reading, and happy coding!
Original article source at https://blog.logrocket.com
#react #radix
1606707213
Radix is the first layer-one protocol specifically built to serve DeFi. Decentralized finance applications are currently built on protocols that are not fit for purpose, leading to congestion, hacks and developer frustration. Radix changes this by introducing a scalable, secure-by-design, composable platform with a DeFi specific build environment to make it easy to build and launch scalable DeFi.
DeFi is a booming sector. But with this craze around the latter, users have observed limits to certain protocols, such as Ethereum (ETH) and its fees which were exploding day by day. And despite days and days of tearing our hair out, the solution is not yet there … Radix then arrived in this context by coming to propose a Blockchain based on a new consensus: Cerberus. Thanks to the latter but also to all the building blocks developed around it, Radix has specialized in processing DeFi applications. Explanations.
Warning : This sponsored article is offered to you in partnership with the company Radix. Crypto investments are risky by nature, do your own research and invest only within the limits of your financial capacity. This article does not constitute an investment invitation.
Radix starts from a simple premise: DeFi is the future of finance. The second assumption is the following: today, no Blockchain succeeds in satisfying the needs of DeFi.
And Radix intends to solve this problem! To do so, the team behind Radix focused on 3 points that they considered essential:
And finally, these three points go together to form a virtuous circle.
Image taken from radixdlt.com
Indeed, accessibility leads to a greater number of users, which then leads to more liquidity, which leads to a greater number of actors wanting to come, who themselves attract more users … You understand the principle!
And all this wouldn’t work without this new consensus: Cerberus! He really is the foundation of everything. Although this is a bit technical, we invite you to read the latter’s whitepaper if you are interested!
To put it simply, Cerberus is part of the so-called “braiding” consensus family. The advantage of this consensus family is that it allows the parallelism of many treatments. Behind this weird word is simply the fact of being able to perform several tasks simultaneously.
Thanks to this, the theoretical scalability of Radix is infinite. In fact, it is directly linked to the number of nodes present on the network. Thus, the more successful the Radix blockchain, the more users and applications there will be, and the more nodes there will be, and therefore the more scalability will increase. A globally winning context!
On the team side, it is rather well supplied, with many people making it up, especially on the IT development aspect.
If ever the project interests you and you want to learn more about how Radix responds to DeFi issues, the project has written a whitepaper dedicated to it!
As of this writing (early October 2020), the Radix mainnet is yet to be launched. It is scheduled for 2021.
In the meantime, the project is not left with nothing! And the token native to this blockchain, the XRD, will be represented by its equivalent in ERC20: the eXRD.
When the mainnet is launched, you will then be able to exchange your eXRDs for XRDs with a ratio of 1 to 1.
Interestingly, the supply of XRD will be managed according to specific rules.
First of all, the generation of XRD will not be done by validating a block, but by the price of the block:
The goal, according to the team, behind this show is to only create tokens if they are used. So the supply is supposed to represent Radix’s adoption, not just its longevity since launch.
Finally, XRD has an important feature: its rarefaction. Indeed, during a transaction, the transaction fees will burn. Burn is a process of destroying tokens by sending them to an unusable address.
Would you like to earn token right now! ☞ CLICK HERE
Looking for more information…
☞ Website
☞ Explorer
☞ Source Code
☞ Social Channel
☞ Message Board
☞ Coinmarketcap
Thank you for reading! I’m highly appreciate your actions! Please share if you liked it!
#blockchain #bitcoin #crypto #radix #exrd
1602728640
Long before the invention of Bitcoin, the computerized world has become dependent on open source developers. Some pieces of code such as Internet browsers, operating systems, and code libraries have become so essential that it is unanimously agreed upon that they should not be controlled by a single company, who might charge exorbitant fees for their usage, withhold the software from certain users for any reason, or do other nefarious things with the code.
With the advent of cryptocurrencies and decentralized finance (DeFi), open source development has become more important than ever. However, there is a noticeable lack of professional developers in DeFi. As a result, many emerging DeFi platforms go live as largely untested garage enterprises. Oftentimes, new DeFi smart contracts can attract millions of dollars in locked value, although there has been next to no auditing.
For example, the DeFi platform YAM encountered a small but critical bug in their code, which led to massive loss of funds only a few days after the platform was launched. The platform was rushed and it’s smart contracts were never audited. While DeFi’s approach to breakneck innovation is certainly a good thing, developers lack the right tools to avoid critical mistakes and monetary incentives are a big part of this equation.
The nature of non-profit open source development has it that the initiators of DeFi projects often cannot expect their inventions to generate significant revenue. It is thus very difficult to find professional developers and auditors. While volunteer work is an absolute must-have in a world that is becoming more and more dependent on code, there is a lot of money at stake in DeFi.
Sadly, developers are seeing very little from this money. As an investor, would you entrust a DeFi platform with your money, knowing that it was hacked together in a few days by developers who have no monetary incentive for the platform to succeed?
For individual open source developers, there currently is little money to be made in DeFi. Most blockchain projects are either funded by various high-dollar development funds run by the big blockchain platforms, or through venture capital. While venture capitalists typically require their funded projects to be profit-oriented, blockchain development funds are often not optimal for DeFi projects.
These funds usually incentivize development on a specific blockchain as part of their ecosystem building. This leads to DeFi projects often becoming mere copy-cats of existing DApps on Ethereum, with no real innovation. Also, this incentivizes only the development of complete user-facing DApps.
What is needed is a more granular revenue stream that is oriented towards individuals. A single developer who can solve a difficult problem in an elegant way can often generate more value to a blockchain ecosystem than a full-fledged DeFi DApp, but oftentimes, coders who develop these building blocks either don’t have the connections that allow them to turn them into a complete DApp, or they simply do not have an interest in doing so.
#blockchain #defi #radix #blockchain-developer #blockchain-top-story #what-is-dlt #defi-top-story #open-source-incentivization