-
-
Notifications
You must be signed in to change notification settings - Fork 60
Add documentation for prompt types and validators #341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| name: Deploy docs to GitHub Pages | ||
|
|
||
| on: | ||
| push: | ||
| branches: [master] | ||
| paths: | ||
| - 'docs/**' | ||
| - '.github/workflows/docs.yml' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pages: write | ||
| id-token: write | ||
|
|
||
| concurrency: | ||
| group: pages | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| defaults: | ||
| run: | ||
| working-directory: docs | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
|
|
||
| - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 | ||
| with: | ||
| node-version-file: docs/package.json | ||
| cache: npm | ||
| cache-dependency-path: docs/package-lock.json | ||
|
|
||
| - run: npm ci | ||
| - run: npm run docs:build | ||
|
|
||
| - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 | ||
|
|
||
| - uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 | ||
| with: | ||
| path: docs/.vitepress/dist | ||
|
|
||
| deploy: | ||
| runs-on: ubuntu-latest | ||
| needs: build | ||
| steps: | ||
| - uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,56 @@ | ||||||
| import { defineConfig } from 'vitepress' | ||||||
|
|
||||||
| export default defineConfig({ | ||||||
| title: 'Sharprompt', | ||||||
| description: 'Interactive command-line based application framework for C#', | ||||||
| base: '/Sharprompt/', | ||||||
| cleanUrls: true, | ||||||
| head: [ | ||||||
| ['link', { rel: 'icon', href: '/Sharprompt/icon.png' }] | ||||||
|
||||||
| ['link', { rel: 'icon', href: '/Sharprompt/icon.png' }] | |
| ['link', { rel: 'icon', href: '/icon.png' }] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| :root { | ||
| /* Icon Blue */ | ||
| --vp-c-brand-1: #4878b8; | ||
| --vp-c-brand-2: #3d6aa8; | ||
| --vp-c-brand-3: #345d96; | ||
| --vp-c-brand-soft: rgba(72, 120, 184, 0.14); | ||
|
|
||
| /* Hero gradient */ | ||
| --vp-home-hero-name-color: transparent; | ||
| --vp-home-hero-name-background: linear-gradient(135deg, #4878b8, #5a9bd6); | ||
| --vp-home-hero-image-background-image: linear-gradient(135deg, rgba(72, 120, 184, 0.2), rgba(90, 155, 214, 0.2)); | ||
| --vp-home-hero-image-filter: blur(44px); | ||
| } | ||
|
|
||
| .dark { | ||
| --vp-c-brand-1: #6fa8dc; | ||
| --vp-c-brand-2: #5a9bd6; | ||
| --vp-c-brand-3: #4878b8; | ||
| --vp-c-brand-soft: rgba(111, 168, 220, 0.14); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| import DefaultTheme from 'vitepress/theme' | ||
| import './custom.css' | ||
|
|
||
| export default DefaultTheme |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # Advanced Features | ||
|
|
||
| ## Enum Type Support | ||
|
|
||
| When using an enum type with `Select` or `MultiSelect`, items are automatically generated from the enum values. You can use the `[Display]` attribute to customize the display names: | ||
|
|
||
| ```csharp | ||
| using System.ComponentModel.DataAnnotations; | ||
|
|
||
| public enum MyEnum | ||
| { | ||
| [Display(Name = "First value")] | ||
| First, | ||
| [Display(Name = "Second value")] | ||
| Second, | ||
| [Display(Name = "Third value")] | ||
| Third | ||
| } | ||
|
|
||
| var value = Prompt.Select<MyEnum>("Select enum value"); | ||
| Console.WriteLine($"You selected {value}"); | ||
| ``` | ||
|
|
||
| For `MultiSelect`: | ||
|
|
||
| ```csharp | ||
| var values = Prompt.MultiSelect<MyEnum>("Select enum values"); | ||
| Console.WriteLine($"You picked {string.Join(", ", values)}"); | ||
| ``` | ||
|
|
||
| ## Unicode Support | ||
|
|
||
| Sharprompt supports multi-byte characters and emoji. For best results, set the output encoding to UTF-8: | ||
|
|
||
| ```csharp | ||
| Console.OutputEncoding = Encoding.UTF8; | ||
|
|
||
| var name = Prompt.Input<string>("What's your name?"); | ||
| Console.WriteLine($"Hello, {name}!"); | ||
| ``` | ||
|
|
||
| ## Fluent Interface | ||
|
|
||
| All prompt types support a fluent interface via the `Sharprompt.Fluent` namespace: | ||
|
|
||
| ```csharp | ||
| using Sharprompt.Fluent; | ||
|
|
||
| var city = Prompt.Select<string>(o => o.WithMessage("Select your city") | ||
| .WithItems(new[] { "Seattle", "London", "Tokyo" }) | ||
| .WithDefaultValue("Seattle")); | ||
| ``` | ||
|
|
||
| The fluent API provides `With*` methods for setting properties and `Add*` methods for adding to collections (like validators). | ||
|
|
||
| ## Text Selector | ||
|
|
||
| For `Select` and `MultiSelect`, you can provide a custom function to control how items are displayed: | ||
|
|
||
| ```csharp | ||
| var user = Prompt.Select("Select user", users, textSelector: u => u.Name); | ||
| ``` | ||
|
|
||
| ## Pagination | ||
|
|
||
| Both `Select` and `MultiSelect` support pagination via the `pageSize` parameter: | ||
|
|
||
| ```csharp | ||
| var city = Prompt.Select("Select your city", | ||
| new[] { "Seattle", "London", "Tokyo", "New York", "Singapore", "Shanghai" }, | ||
| pageSize: 3); | ||
| ``` | ||
|
|
||
| ## Looping Selection | ||
|
|
||
| By default, selection lists loop when reaching the beginning or end. This can be disabled via the options class: | ||
|
|
||
| ```csharp | ||
| var city = Prompt.Select(new SelectOptions<string> | ||
| { | ||
| Message = "Select your city", | ||
| Items = new[] { "Seattle", "London", "Tokyo" }, | ||
| LoopingSelection = false | ||
| }); | ||
| ``` |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,85 @@ | ||||||
| # Configuration | ||||||
|
|
||||||
| Sharprompt allows you to customize the appearance and behavior of prompts globally. | ||||||
|
|
||||||
| ## Symbols | ||||||
|
|
||||||
| You can customize the symbols used by prompts: | ||||||
|
|
||||||
| ```csharp | ||||||
| Prompt.Symbols.Prompt = new Symbol("🤔", "?"); | ||||||
| Prompt.Symbols.Done = new Symbol("😎", "V"); | ||||||
| Prompt.Symbols.Error = new Symbol("😱", ">>"); | ||||||
|
|
||||||
| var name = Prompt.Input<string>("What's your name?"); | ||||||
| ``` | ||||||
|
|
||||||
| The `Symbol` class takes two arguments: a Unicode value and a fallback value for terminals that don't support Unicode. | ||||||
|
|
||||||
| ### Available Symbols | ||||||
|
|
||||||
| | Symbol | Default (Unicode) | Default (Fallback) | Description | | ||||||
| |--------|-------------------|-------------------|-------------| | ||||||
| | `Prompt` | `?` | `?` | Displayed before the prompt message | | ||||||
| | `Done` | `✔` | `V` | Displayed when the prompt is completed | | ||||||
| | `Error` | `»` | `>>` | Displayed when validation fails | | ||||||
| | `Selector` | `›` | `>` | Points to the currently highlighted item | | ||||||
| | `Selected` | `◉` | `(*)` | Marks a selected item in MultiSelect | | ||||||
| | `NotSelect` | `◯` | `( )` | Marks an unselected item in MultiSelect | | ||||||
|
|
||||||
| ## Color Schema | ||||||
|
|
||||||
| Customize the colors used by prompts: | ||||||
|
|
||||||
| ```csharp | ||||||
| Prompt.ColorSchema.Answer = ConsoleColor.DarkRed; | ||||||
| Prompt.ColorSchema.Select = ConsoleColor.DarkCyan; | ||||||
|
|
||||||
| var name = Prompt.Input<string>("What's your name?"); | ||||||
| ``` | ||||||
|
|
||||||
| ### Available Colors | ||||||
|
|
||||||
| | Property | Default | Description | | ||||||
| |----------|---------|-------------| | ||||||
| | `DoneSymbol` | `Green` | Color of the done symbol | | ||||||
| | `PromptSymbol` | `Green` | Color of the prompt symbol | | ||||||
| | `Answer` | `Cyan` | Color of the user's answer | | ||||||
| | `Select` | `Green` | Color of the selected item | | ||||||
| | `Error` | `Red` | Color of error messages | | ||||||
| | `Hint` | `DarkGray` | Color of hints and placeholders | | ||||||
| | `DisabledOption` | `DarkCyan` | Color of disabled options | | ||||||
|
|
||||||
| ## Cancellation Support | ||||||
|
|
||||||
| By default, pressing `Ctrl+C` returns the default value. You can change this behavior to throw an exception: | ||||||
|
||||||
| By default, pressing `Ctrl+C` returns the default value. You can change this behavior to throw an exception: | |
| By default, pressing `Ctrl+C` cancels the prompt and terminates the process (for example with exit code `1`). You can change this behavior to throw an exception instead of exiting: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| # Getting Started | ||
|
|
||
| ## Installation | ||
|
|
||
| Install Sharprompt via NuGet: | ||
|
|
||
| ::: code-group | ||
|
|
||
| ```powershell [Package Manager] | ||
| Install-Package Sharprompt | ||
| ``` | ||
|
|
||
| ```sh [.NET CLI] | ||
| dotnet add package Sharprompt | ||
| ``` | ||
|
|
||
| ::: | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ```csharp | ||
| using Sharprompt; | ||
|
|
||
| // Simple input | ||
| var name = Prompt.Input<string>("What's your name?"); | ||
| Console.WriteLine($"Hello, {name}!"); | ||
|
|
||
| // Password input | ||
| var secret = Prompt.Password("Type new password", | ||
| validators: new[] { Validators.Required(), Validators.MinLength(8) }); | ||
| Console.WriteLine("Password OK"); | ||
|
|
||
| // Confirmation | ||
| var answer = Prompt.Confirm("Are you ready?", defaultValue: true); | ||
| Console.WriteLine($"Your answer is {answer}"); | ||
| ``` | ||
|
|
||
| ## Running the Examples | ||
|
|
||
| The repository includes a sample project with all prompt types: | ||
|
|
||
| ```sh | ||
| dotnet run --project samples/Sharprompt.Example | ||
| ``` | ||
|
|
||
| ## Supported Platforms | ||
|
|
||
| | Platform | Terminal | | ||
| |----------|----------| | ||
| | Windows | Command Prompt, PowerShell, Windows Terminal | | ||
| | Linux | Windows Terminal (WSL 2), various terminal emulators | | ||
| | macOS | Terminal.app, iTerm2, etc. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actions/setup-nodeis configured withnode-version-file: docs/package.json, but that file doesn't define anengines.nodefield (it only has avoltasection).setup-nodetypically reads Node version from.nvmrc/.node-versionorpackage.json#engines.node, so this is likely to fail or pick an unintended Node version, which can break the docs build (Vite/VitePress have Node minimums). Consider either adding anengines.nodeentry, adding a.nvmrc/.node-versionfile and pointingnode-version-fileto it, or settingnode-versionexplicitly in the workflow.